MONC
Data Types | Functions/Subroutines | Variables
writer_field_manager_mod Module Reference

The writer field manager will manage aspects of the fields being provided to the writer federator. There are two major aspects to this, firstly extraction of fields from the data sent directly from MONC and then passed on if these fields are needed. Secondly, this will queue up the data to ensure that it is sent to the writer federator in strict order and that only one piece of a fields data is in the writer federator at any one time. More...

Data Types

type  field_ordering_type
 
type  field_ordering_value_type
 
interface  provide_field_to_writer_federator
 

Functions/Subroutines

subroutine, public initialise_writer_field_manager (io_configuration, continuation_run)
 Initialises the writer field manager. More...
 
subroutine, public finalise_writer_field_manager ()
 Finalises the writer field manager. More...
 
logical function, public is_write_field_manager_up_to_date (timestep)
 Determines whether the state of the write field manager is up to date with respect to the timestep that has been provided, checks each entry to see if it is missing data or not. More...
 
subroutine, public provide_monc_data_to_writer_federator (io_configuration, source, data_id, data_dump)
 Data communicated from MONC is provided to this write federator and then included if the configuration has selected to use that MONC field (as opposed to a field produced by the diagnostics federator) More...
 
type(data_values_type) function get_value_from_monc_data (io_configuration, source, data_id, data_dump, field_name, field_namespace)
 Retrieves a value from the communicated MONC data. If this was an integer then converts to a real. More...
 
subroutine get_type_of_field (fields, field_name, field_namespace, field_type, data_type)
 Retrieves the data type of a field or 0 if the field was not found. More...
 
subroutine provide_field_to_writer_federator_rvalues_src (io_configuration, field_name, field_namespace, field_values, timestep, time, frequency, source)
 
subroutine provide_field_to_writer_federator_rvalues_nosrc (io_configuration, field_name, field_namespace, field_values, timestep, time, frequency)
 
subroutine provide_field_to_writer_federator_nosrc (io_configuration, field_name, field_namespace, field_values, timestep, time, frequency)
 Provides a field to the write federator with no source (a none collective diagnostic) More...
 
subroutine provide_field_to_writer_federator_src (io_configuration, field_name, field_namespace, field_values, timestep, time, frequency, source, terminated_case)
 Provides a field to the write federator (a collective diagnostic or prognostic) More...
 
subroutine process_queued_items (io_configuration, field_ordering)
 Processes queued up items for a specific field's ordering. This will send any available fields to the write federator with a guaranteed ordering and clean up the memory associated with them. More...
 
type(field_ordering_value_type) function, pointer get_field_ordering_value_at_timestep (collection, timestep)
 Retrieves a specific field ordering value at the corresponding timestep or null if none is found. More...
 
type(field_ordering_value_type) function, pointer generate_value_container (field_name, field_namespace, field_values, timestep, time, frequency, source)
 Generates the field value container which is then filled in with appropriate values and added into the overall field ordering data structure. More...
 
type(field_ordering_type) function, pointer get_or_add_field_ordering (field_name, field_namespace, frequency, source)
 Retrieves or adds ordering for a specific field (and MONC source) More...
 
type(field_ordering_type) function, pointer get_field_ordering (field_name, do_lock)
 Retrieves a field ordering based upon the name or null if none can be found. More...
 
integer(kind=8) function prepare_to_serialise_field_manager_state ()
 Prepares to serialise the field manager state, both determines storage needed and also issues any locks. More...
 
subroutine serialise_field_manager_state (byte_data)
 Serialises the current field manager, releases any locks issued during preparation. More...
 
subroutine unserialise_field_manager_state (byte_data)
 Unserialses from some byte data into the state. More...
 
integer(kind=8) function prepare_to_serialise_specific_field_ordering (specific_field_ordering)
 Prepares to serialise a specific field ordering, both determines storage size and issues locks. More...
 
subroutine serialise_specific_field_ordering (specific_field_ordering, byte_data, current_data_point)
 Serialises a specific fields ordering and releases any locks issued during preparation. More...
 
type(field_ordering_type) function, pointer unserialise_specific_field_ordering (byte_data)
 Unserialises some field ordering. More...
 
integer(kind=8) function prepare_to_serialise_field_ordering_value (specific_field_value)
 Prepares to serialise a specific field ordering value, determines both the storage size and issues locks. More...
 
subroutine serialise_field_ordering_value (specific_field_value, byte_data, current_data_point)
 Serialises a field ordering value and releases any issued locks. More...
 
type(field_ordering_value_type) function, pointer unserialise_field_ordering_value (byte_data)
 Unseralises some field ordering from its byte representation. More...
 

Variables

integer, volatile field_lock
 
type(hashmap_type), volatile field_orderings
 

Detailed Description

The writer field manager will manage aspects of the fields being provided to the writer federator. There are two major aspects to this, firstly extraction of fields from the data sent directly from MONC and then passed on if these fields are needed. Secondly, this will queue up the data to ensure that it is sent to the writer federator in strict order and that only one piece of a fields data is in the writer federator at any one time.

Function/Subroutine Documentation

◆ finalise_writer_field_manager()

subroutine, public writer_field_manager_mod::finalise_writer_field_manager ( )

Finalises the writer field manager.

Definition at line 72 of file writer_field_manager.F90.

72  call check_thread_status(forthread_rwlock_destroy(field_lock))
Here is the call graph for this function:
Here is the caller graph for this function:

◆ generate_value_container()

type(field_ordering_value_type) function, pointer writer_field_manager_mod::generate_value_container ( character(len=*), intent(in)  field_name,
character(len=*), intent(in)  field_namespace,
type(data_values_type), intent(in)  field_values,
integer, intent(in)  timestep,
real(kind=default_precision), intent(in)  time,
integer, intent(in)  frequency,
integer, intent(in)  source 
)
private

Generates the field value container which is then filled in with appropriate values and added into the overall field ordering data structure.

Parameters
field_nameThe field name
field_valuesThe fields values
timestepThe corresponding MONC model timestep
timeThe corresponding MONC model time
frequencyConfigured sampling frequency
sourceMONC source pid
Returns
A value container which can be added into the field ordering data structure

Definition at line 376 of file writer_field_manager.F90.

376  character(len=*), intent(in) :: field_name, field_namespace
377  integer, intent(in) :: timestep, frequency, source
378  type(data_values_type), intent(in) :: field_values
379  real(kind=DEFAULT_PRECISION), intent(in) :: time
380  type(field_ordering_value_type), pointer :: generate_value_container
381 
382  allocate(generate_value_container)
383  generate_value_container%field_name=field_name
384  generate_value_container%field_namespace=field_namespace
385  generate_value_container%timestep=timestep
386  generate_value_container%frequency=frequency
387  generate_value_container%time=time
388  generate_value_container%source=source
389  allocate(generate_value_container%field_values, source=field_values)
Here is the caller graph for this function:

◆ get_field_ordering()

type(field_ordering_type) function, pointer writer_field_manager_mod::get_field_ordering ( character(len=*), intent(in)  field_name,
logical, intent(in)  do_lock 
)
private

Retrieves a field ordering based upon the name or null if none can be found.

Parameters
field_nameThe name of the field to look up
do_lockWhether to issue a read lock or not
Returns
The corresponding field ordering data structure or null if none is found

Definition at line 432 of file writer_field_manager.F90.

432  character(len=*), intent(in) :: field_name
433  logical, intent(in) :: do_lock
434  type(field_ordering_type), pointer :: get_field_ordering
435 
436  class(*), pointer :: generic
437 
438  if (do_lock) call check_thread_status(forthread_rwlock_rdlock(field_lock))
439  generic=>c_get_generic(field_orderings, field_name)
440  if (do_lock) call check_thread_status(forthread_rwlock_unlock(field_lock))
441  if (associated(generic)) then
442  select type(generic)
443  type is (field_ordering_type)
444  get_field_ordering=>generic
445  end select
446  else
447  get_field_ordering=>null()
448  end if
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_field_ordering_value_at_timestep()

type(field_ordering_value_type) function, pointer writer_field_manager_mod::get_field_ordering_value_at_timestep ( type(hashmap_type), intent(inout)  collection,
integer, intent(in)  timestep 
)
private

Retrieves a specific field ordering value at the corresponding timestep or null if none is found.

Parameters
collectionThe map of timesteps to field ordering values that we are looking up
timestepThe timestep to look up
Returns
The corresponding field ordering or null if none is found

Definition at line 349 of file writer_field_manager.F90.

349  type(hashmap_type), intent(inout) :: collection
350  integer, intent(in) :: timestep
351  type(field_ordering_value_type), pointer :: get_field_ordering_value_at_timestep
352 
353  class(*), pointer :: generic
354 
355  generic=>c_get_generic(collection, conv_to_string(timestep))
356  if (associated(generic)) then
357  select type(generic)
358  type is (field_ordering_value_type)
359  get_field_ordering_value_at_timestep=>generic
360  end select
361  else
362  get_field_ordering_value_at_timestep=>null()
363  end if
Here is the caller graph for this function:

◆ get_or_add_field_ordering()

type(field_ordering_type) function, pointer writer_field_manager_mod::get_or_add_field_ordering ( character(len=*), intent(in)  field_name,
character(len=*), intent(in)  field_namespace,
integer, intent(in)  frequency,
integer, intent(in)  source 
)
private

Retrieves or adds ordering for a specific field (and MONC source)

Parameters
field_nameThe field name
frequencyThe sampling frequency of this field
sourceMONC source PID
Returns
Either the existing or a newly created field ordering

Definition at line 398 of file writer_field_manager.F90.

398  character(len=*), intent(in) :: field_name, field_namespace
399  integer, intent(in) :: frequency, source
400  type(field_ordering_type), pointer :: get_or_add_field_ordering
401 
402  class(*), pointer :: generic
403  character(len=STRING_LENGTH) :: entry_key
404 
405  if (source .gt. -1) then
406  entry_key=trim(field_name)//"#"//trim(field_namespace)//"#"//trim(conv_to_string(source))
407  else
408  entry_key=field_name
409  end if
410 
411  get_or_add_field_ordering=>get_field_ordering(entry_key, .true.)
412  if (.not. associated(get_or_add_field_ordering)) then
413  call check_thread_status(forthread_rwlock_wrlock(field_lock))
414  get_or_add_field_ordering=>get_field_ordering(entry_key, .false.)
415  if (.not. associated(get_or_add_field_ordering)) then
416  allocate(get_or_add_field_ordering)
417  get_or_add_field_ordering%last_timestep_access=0
418  get_or_add_field_ordering%frequency=frequency
419  call check_thread_status(forthread_mutex_init(get_or_add_field_ordering%access_mutex, -1))
420  generic=>get_or_add_field_ordering
421  call c_put_generic(field_orderings, entry_key, generic, .false.)
422  end if
423  call check_thread_status(forthread_rwlock_unlock(field_lock))
424  end if
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_type_of_field()

subroutine writer_field_manager_mod::get_type_of_field ( type(io_configuration_field_type), dimension(:), intent(in)  fields,
character(len=*), intent(in)  field_name,
character(len=*), intent(in)  field_namespace,
integer, intent(out)  field_type,
integer, intent(out)  data_type 
)
private

Retrieves the data type of a field or 0 if the field was not found.

Parameters
fieldsArray of fields to search
field_nameThe name of the field to locate
Returns
The data type of this field or 0 if the field was not found

Definition at line 204 of file writer_field_manager.F90.

204  type(io_configuration_field_type), dimension(:), intent(in) :: fields
205  character(len=*), intent(in) :: field_name, field_namespace
206  integer, intent(out) :: field_type, data_type
207 
208  integer :: i
209 
210  do i=1, size(fields)
211  if (fields(i)%name .eq. field_name .and. fields(i)%namespace .eq. field_namespace) then
212  data_type=fields(i)%data_type
213  field_type=fields(i)%field_type
214  return
215  end if
216  end do
217  data_type=0
218  field_type=0
Here is the caller graph for this function:

◆ get_value_from_monc_data()

type(data_values_type) function writer_field_manager_mod::get_value_from_monc_data ( type(io_configuration_type), intent(inout)  io_configuration,
integer, intent(in)  source,
integer, intent(in)  data_id,
character, dimension(:), intent(in), allocatable  data_dump,
character(len=*), intent(in)  field_name,
character(len=*), intent(in)  field_namespace 
)
private

Retrieves a value from the communicated MONC data. If this was an integer then converts to a real.

Parameters
io_configurationConfiguration of the IO server
sourceThe source PID of the MONC process
data_idThe ID of the data definition that is represented by the dump
data_dumpThe data we have received from MONC
field_nameThe field to retrieve
Returns
Data value wrapper containing the values and meta-data

Definition at line 159 of file writer_field_manager.F90.

159  type(io_configuration_type), intent(inout) :: io_configuration
160  integer, intent(in) :: source, data_id
161  character, dimension(:), allocatable, intent(in) :: data_dump
162  character(len=*), intent(in) :: field_name, field_namespace
163  type(data_values_type) :: get_value_from_monc_data
164  type(map_type) :: retrieved_map
165  type(iterator_type) :: iterator
166  type(mapentry_type) :: map_entry
167 
168  integer :: field_data_type, field_field_type, i
169  integer, dimension(:), allocatable :: int_values
170 
171  call get_type_of_field(io_configuration%data_definitions(data_id)%fields, field_name, field_namespace, &
172  field_field_type, field_data_type)
173  if (field_data_type == 0) then
174  call log_log(log_error, "No data type for field '"//trim(field_name)//"'")
175  end if
176 
177  if (field_data_type == double_data_type) then
178  get_value_from_monc_data%values=get_array_double_from_monc(io_configuration, source, data_id, data_dump, field_name)
179  get_value_from_monc_data%data_type=double_data_type
180  else if (field_data_type == integer_data_type) then
181  get_value_from_monc_data%data_type=double_data_type
182  int_values=get_array_integer_from_monc(io_configuration, source, data_id, data_dump, field_name)
183  allocate(get_value_from_monc_data%values(size(int_values)))
184  do i=1, size(int_values)
185  get_value_from_monc_data%values(i)=conv_to_real(int_values(i))
186  end do
187  deallocate(int_values)
188  else if (field_data_type == string_data_type) then
189  get_value_from_monc_data%data_type=string_data_type
190  if (field_field_type == scalar_field_type) then
191  allocate(get_value_from_monc_data%string_values(1))
192  get_value_from_monc_data%string_values(1)=get_string_from_monc(io_configuration, source, data_id, data_dump, field_name)
193  else if (field_field_type == map_field_type) then
194  get_value_from_monc_data%map_values=get_map_from_monc(io_configuration, source, data_id, data_dump, field_name)
195  end if
196  end if
Here is the call graph for this function:
Here is the caller graph for this function:

◆ initialise_writer_field_manager()

subroutine, public writer_field_manager_mod::initialise_writer_field_manager ( type(io_configuration_type), intent(inout)  io_configuration,
logical, intent(in)  continuation_run 
)

Initialises the writer field manager.

Parameters
io_configurationConfiguration of the IO server
continuation_runWhether or not this is a continuation run

Definition at line 59 of file writer_field_manager.F90.

59  type(io_configuration_type), intent(inout) :: io_configuration
60  logical, intent(in) :: continuation_run
61 
62  call check_thread_status(forthread_rwlock_init(field_lock, -1))
63  call set_serialise_write_field_manager_state(serialise_field_manager_state, prepare_to_serialise_field_manager_state, &
64  is_write_field_manager_up_to_date)
65  if (continuation_run) then
66  call reactivate_writer_field_manager_state(io_configuration, unserialise_field_manager_state)
67  end if
Here is the call graph for this function:
Here is the caller graph for this function:

◆ is_write_field_manager_up_to_date()

logical function, public writer_field_manager_mod::is_write_field_manager_up_to_date ( integer, intent(in)  timestep)

Determines whether the state of the write field manager is up to date with respect to the timestep that has been provided, checks each entry to see if it is missing data or not.

Parameters
timestepThe timestep to check against
Returns
Whether the write field manager is up to date or not

Definition at line 80 of file writer_field_manager.F90.

80  integer, intent(in) :: timestep
81 
82  type(iterator_type) :: iterator
83  type(mapentry_type) :: mapentry
84  class(*), pointer :: generic
85 
86  is_write_field_manager_up_to_date=.true.
87  call check_thread_status(forthread_rwlock_rdlock(field_lock))
88  iterator=c_get_iterator(field_orderings)
89  do while (c_has_next(iterator))
90  mapentry=c_next_mapentry(iterator)
91  generic=>c_get_generic(mapentry)
92  select type(generic)
93  type is (field_ordering_type)
94  if (generic%last_timestep_access .lt. timestep) then
95  is_write_field_manager_up_to_date=.false.
96  exit
97  end if
98  end select
99  end do
100  call check_thread_status(forthread_rwlock_unlock(field_lock))
Here is the call graph for this function:
Here is the caller graph for this function:

◆ prepare_to_serialise_field_manager_state()

integer(kind=8) function writer_field_manager_mod::prepare_to_serialise_field_manager_state ( )
private

Prepares to serialise the field manager state, both determines storage needed and also issues any locks.

Returns
The number of bytes needed to store the serialised state

Definition at line 454 of file writer_field_manager.F90.

454  type(mapentry_type) :: map_entry
455  type(iterator_type) :: iterator
456  class(*), pointer :: generic
457 
458  call check_thread_status(forthread_rwlock_rdlock(field_lock))
459  prepare_to_serialise_field_manager_state=kind(prepare_to_serialise_field_manager_state)
460 
461  iterator=c_get_iterator(field_orderings)
462  do while (c_has_next(iterator))
463  map_entry=c_next_mapentry(iterator)
464  generic=>c_get_generic(map_entry)
465  if (associated(generic)) then
466  select type(generic)
467  type is (field_ordering_type)
468  prepare_to_serialise_field_manager_state=prepare_to_serialise_field_manager_state+&
469  prepare_to_serialise_specific_field_ordering(generic)+&
470  (kind(prepare_to_serialise_field_manager_state)*2)+len(trim(map_entry%key))
471  end select
472  end if
473  end do
Here is the call graph for this function:
Here is the caller graph for this function:

◆ prepare_to_serialise_field_ordering_value()

integer(kind=8) function writer_field_manager_mod::prepare_to_serialise_field_ordering_value ( type(field_ordering_value_type), intent(inout)  specific_field_value)
private

Prepares to serialise a specific field ordering value, determines both the storage size and issues locks.

Parameters
specific_field_valueThe specific value to prepare for serialisation
Returns
The number of bytes needed to store the serialised state

Definition at line 645 of file writer_field_manager.F90.

645  type(field_ordering_value_type), intent(inout) :: specific_field_value
646 
647  prepare_to_serialise_field_ordering_value=prepare_to_serialise_data_values_type(specific_field_value%field_values)
648  prepare_to_serialise_field_ordering_value=prepare_to_serialise_field_ordering_value+&
649  (kind(specific_field_value%timestep) * 6) + len(trim(specific_field_value%field_name)) + &
650  len(trim(specific_field_value%field_namespace)) + kind(specific_field_value%time)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ prepare_to_serialise_specific_field_ordering()

integer(kind=8) function writer_field_manager_mod::prepare_to_serialise_specific_field_ordering ( type(field_ordering_type), intent(inout)  specific_field_ordering)
private

Prepares to serialise a specific field ordering, both determines storage size and issues locks.

Parameters
specific_field_orderingThe field ordering to prepare for serialisation
Returns
The number of bytes needed to store the serialised state

Definition at line 542 of file writer_field_manager.F90.

542  type(field_ordering_type), intent(inout) :: specific_field_ordering
543 
544  type(mapentry_type) :: map_entry
545  type(iterator_type) :: iterator
546  class(*), pointer :: generic
547 
548  call check_thread_status(forthread_mutex_lock(specific_field_ordering%access_mutex))
549 
550  prepare_to_serialise_specific_field_ordering=kind(prepare_to_serialise_specific_field_ordering) * 3
551 
552  iterator=c_get_iterator(specific_field_ordering%timestep_to_value)
553  do while (c_has_next(iterator))
554  map_entry=c_next_mapentry(iterator)
555  generic=>c_get_generic(map_entry)
556  if (associated(generic)) then
557  select type(generic)
558  type is (field_ordering_value_type)
559  prepare_to_serialise_specific_field_ordering=prepare_to_serialise_specific_field_ordering+&
560  prepare_to_serialise_field_ordering_value(generic)+(kind(prepare_to_serialise_specific_field_ordering)*2)+&
561  len(trim(map_entry%key))
562  end select
563  end if
564  end do
Here is the call graph for this function:
Here is the caller graph for this function:

◆ process_queued_items()

subroutine writer_field_manager_mod::process_queued_items ( type(io_configuration_type), intent(inout)  io_configuration,
type(field_ordering_type), intent(inout)  field_ordering 
)
private

Processes queued up items for a specific field's ordering. This will send any available fields to the write federator with a guaranteed ordering and clean up the memory associated with them.

Parameters
io_configurationThe IO server configuration
field_orderingThe field ordering status associated with this field

Definition at line 316 of file writer_field_manager.F90.

316  type(io_configuration_type), intent(inout) :: io_configuration
317  type(field_ordering_type), intent(inout) :: field_ordering
318 
319  integer :: next_timestep
320  type(field_ordering_value_type), pointer :: field_ordering_value_at_timestep
321 
322  do while (.not. c_is_empty(field_ordering%timestep_to_value))
323  next_timestep=field_ordering%last_timestep_access + field_ordering%frequency
324  if (c_contains(field_ordering%timestep_to_value, conv_to_string(next_timestep))) then
325  field_ordering_value_at_timestep=>get_field_ordering_value_at_timestep(field_ordering%timestep_to_value, next_timestep)
326  call c_remove(field_ordering%timestep_to_value, conv_to_string(next_timestep))
327  field_ordering%last_timestep_access=next_timestep
328  call provide_ordered_field_to_writer_federator(io_configuration, field_ordering_value_at_timestep%field_name, &
329  field_ordering_value_at_timestep%field_namespace, field_ordering_value_at_timestep%field_values, &
330  field_ordering_value_at_timestep%timestep, field_ordering_value_at_timestep%time, &
331  field_ordering_value_at_timestep%source)
332  if (allocated(field_ordering_value_at_timestep%field_values)) then
333  if (allocated(field_ordering_value_at_timestep%field_values%values)) &
334  deallocate(field_ordering_value_at_timestep%field_values%values)
335  deallocate(field_ordering_value_at_timestep%field_values)
336  end if
337  deallocate(field_ordering_value_at_timestep)
338  else
339  exit
340  end if
341  end do
Here is the call graph for this function:
Here is the caller graph for this function:

◆ provide_field_to_writer_federator_nosrc()

subroutine writer_field_manager_mod::provide_field_to_writer_federator_nosrc ( type(io_configuration_type), intent(inout)  io_configuration,
character(len=*), intent(in)  field_name,
character(len=*), intent(in)  field_namespace,
type(data_values_type), intent(inout)  field_values,
integer, intent(in)  timestep,
real(kind=default_precision), intent(in)  time,
integer, intent(in)  frequency 
)
private

Provides a field to the write federator with no source (a none collective diagnostic)

Parameters
io_configurationThe IO server configuration
field_nameThe field name
field_valuesThe fields values
timestepThe corresponding model timestep
timeCorresponding MONC model time
frequencyConfigured sampling frequency

Definition at line 259 of file writer_field_manager.F90.

259  type(io_configuration_type), intent(inout) :: io_configuration
260  character(len=*), intent(in) :: field_name, field_namespace
261  integer, intent(in) :: timestep, frequency
262  type(data_values_type), intent(inout) :: field_values
263  real(kind=DEFAULT_PRECISION), intent(in) :: time
264 
265  call provide_field_to_writer_federator_src(io_configuration, field_name, field_namespace, &
266  field_values, timestep, time, frequency, -1)
Here is the call graph for this function:

◆ provide_field_to_writer_federator_rvalues_nosrc()

subroutine writer_field_manager_mod::provide_field_to_writer_federator_rvalues_nosrc ( type(io_configuration_type), intent(inout)  io_configuration,
character(len=*), intent(in)  field_name,
character(len=*), intent(in)  field_namespace,
real(kind=default_precision), dimension(:), intent(in)  field_values,
integer, intent(in)  timestep,
real(kind=default_precision), intent(in)  time,
integer, intent(in)  frequency 
)
private

Definition at line 240 of file writer_field_manager.F90.

240  type(io_configuration_type), intent(inout) :: io_configuration
241  character(len=*), intent(in) :: field_name, field_namespace
242  integer, intent(in) :: timestep, frequency
243  real(kind=DEFAULT_PRECISION), dimension(:), intent(in) :: field_values
244  real(kind=DEFAULT_PRECISION), intent(in) :: time
245 
246  call provide_field_to_writer_federator_rvalues_src(io_configuration, field_name, field_namespace, &
247  field_values, timestep, time, frequency, -1)
Here is the call graph for this function:

◆ provide_field_to_writer_federator_rvalues_src()

subroutine writer_field_manager_mod::provide_field_to_writer_federator_rvalues_src ( type(io_configuration_type), intent(inout)  io_configuration,
character(len=*), intent(in)  field_name,
character(len=*), intent(in)  field_namespace,
real(kind=default_precision), dimension(:), intent(in)  field_values,
integer, intent(in)  timestep,
real(kind=default_precision), intent(in)  time,
integer, intent(in)  frequency,
integer, intent(in)  source 
)
private

Definition at line 223 of file writer_field_manager.F90.

223  type(io_configuration_type), intent(inout) :: io_configuration
224  character(len=*), intent(in) :: field_name, field_namespace
225  integer, intent(in) :: timestep, frequency, source
226  real(kind=DEFAULT_PRECISION), dimension(:), intent(in) :: field_values
227  real(kind=DEFAULT_PRECISION), intent(in) :: time
228 
229  type(data_values_type) :: packaged_data
230 
231  allocate(packaged_data%values(size(field_values)))
232  packaged_data%values=field_values
233  packaged_data%data_type=double_data_type
234  call provide_field_to_writer_federator_src(io_configuration, field_name, field_namespace, packaged_data, &
235  timestep, time, frequency, source)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ provide_field_to_writer_federator_src()

subroutine writer_field_manager_mod::provide_field_to_writer_federator_src ( type(io_configuration_type), intent(inout)  io_configuration,
character(len=*), intent(in)  field_name,
character(len=*), intent(in)  field_namespace,
type(data_values_type), intent(inout)  field_values,
integer, intent(in)  timestep,
real(kind=default_precision), intent(in)  time,
integer, intent(in)  frequency,
integer, intent(in)  source,
logical, intent(in), optional  terminated_case 
)
private

Provides a field to the write federator (a collective diagnostic or prognostic)

Parameters
io_configurationThe IO server configuration
field_nameThe field name
field_valuesThe fields values
timestepThe corresponding model timestep
timeCorresponding MONC model time
frequencyConfigured sampling frequency
sourceThe MONC source ID

Definition at line 279 of file writer_field_manager.F90.

279  type(io_configuration_type), intent(inout) :: io_configuration
280  character(len=*), intent(in) :: field_name, field_namespace
281  integer, intent(in) :: timestep, frequency, source
282  type(data_values_type), intent(inout) :: field_values
283  real(kind=DEFAULT_PRECISION), intent(in) :: time
284  logical, intent(in), optional :: terminated_case
285 
286  type(field_ordering_type), pointer :: field_ordering
287  class(*), pointer :: generic
288  logical :: this_is_termination
289 
290  if (present(terminated_case)) then
291  this_is_termination=terminated_case
292  else
293  this_is_termination=.false.
294  end if
295 
296  field_ordering=>get_or_add_field_ordering(field_name, field_namespace, frequency, source)
297  call check_thread_status(forthread_mutex_lock(field_ordering%access_mutex))
298  if (timestep == field_ordering%last_timestep_access + frequency .or. this_is_termination) then
299  if (.not. this_is_termination) field_ordering%last_timestep_access=timestep
300  call provide_ordered_field_to_writer_federator(io_configuration, field_name, field_namespace, &
301  field_values, timestep, time, source)
302  if (allocated(field_values%values)) deallocate(field_values%values)
303  else
304  generic=>generate_value_container(field_name, field_namespace, field_values, timestep, time, frequency, source)
305  call c_put_generic(field_ordering%timestep_to_value, conv_to_string(timestep), generic, .false.)
306  end if
307  call process_queued_items(io_configuration, field_ordering)
308  call check_thread_status(forthread_mutex_unlock(field_ordering%access_mutex))
Here is the call graph for this function:
Here is the caller graph for this function:

◆ provide_monc_data_to_writer_federator()

subroutine, public writer_field_manager_mod::provide_monc_data_to_writer_federator ( type(io_configuration_type), intent(inout)  io_configuration,
integer, intent(in)  source,
integer, intent(in)  data_id,
character, dimension(:), intent(in), allocatable  data_dump 
)

Data communicated from MONC is provided to this write federator and then included if the configuration has selected to use that MONC field (as opposed to a field produced by the diagnostics federator)

Parameters
io_configurationConfiguration of the IO server
sourceThe source PID of the MONC process
data_idThe ID of the data definition that is represented by the dump
data_dumpThe data we have received from MONC

Definition at line 110 of file writer_field_manager.F90.

110  type(io_configuration_type), intent(inout) :: io_configuration
111  integer, intent(in) :: source, data_id
112  character, dimension(:), allocatable, intent(in) :: data_dump
113 
114  integer :: i, num_fields, timestep
115  character(len=STRING_LENGTH) :: field_name, field_namespace
116  real(kind=DEFAULT_PRECISION) :: time
117  type(data_values_type) :: monc_value
118  logical :: terminated_case
119 
120  if (is_field_present(io_configuration, source, data_id, "timestep") .and. &
121  is_field_present(io_configuration, source, data_id, "time")) then
122  timestep=get_scalar_integer_from_monc(io_configuration, source, data_id, data_dump, "timestep")
123  time=get_scalar_real_from_monc(io_configuration, source, data_id, data_dump, "time")
124 
125  if (is_field_present(io_configuration, source, data_id, "terminated")) then
126  terminated_case=get_scalar_logical_from_monc(io_configuration, source, data_id, data_dump, "terminated") .and. &
127  io_configuration%data_definitions(data_id)%send_on_terminate
128  else
129  terminated_case=.false.
130  end if
131 
132  num_fields=io_configuration%data_definitions(data_id)%number_of_data_fields
133 
134  do i=1, num_fields
135  field_name=io_configuration%data_definitions(data_id)%fields(i)%name
136  field_namespace=io_configuration%data_definitions(data_id)%fields(i)%namespace
137  if (is_field_present(io_configuration, source, data_id, field_name) .and. &
138  (is_field_used_by_writer_federator(field_name, field_namespace) .or. is_field_split_on_q(field_name))) then
139  monc_value=get_value_from_monc_data(io_configuration, source, data_id, data_dump, field_name, field_namespace)
140  call provide_field_to_writer_federator_src(io_configuration, field_name, field_namespace, monc_value, timestep, time, &
141  io_configuration%data_definitions(data_id)%frequency, source, terminated_case)
142 
143  !deallocate(monc_value)
144  end if
145  end do
146  else
147  call log_log(log_warn, "Can not run pass MONC fields to writer federator without a time and timestep")
148  end if
Here is the call graph for this function:
Here is the caller graph for this function:

◆ serialise_field_manager_state()

subroutine writer_field_manager_mod::serialise_field_manager_state ( character, dimension(:), intent(inout), allocatable  byte_data)
private

Serialises the current field manager, releases any locks issued during preparation.

Parameters
byte_dataPackaged field manager serialised state.

Definition at line 479 of file writer_field_manager.F90.

479  character, dimension(:), allocatable, intent(inout) :: byte_data
480 
481  integer :: current_data_point, prev_pt
482  type(mapentry_type) :: map_entry
483  type(iterator_type) :: iterator
484  class(*), pointer :: generic
485 
486  current_data_point=1
487  current_data_point=pack_scalar_field(byte_data, current_data_point, c_size(field_orderings))
488 
489  iterator=c_get_iterator(field_orderings)
490  do while (c_has_next(iterator))
491  map_entry=c_next_mapentry(iterator)
492  generic=>c_get_generic(map_entry)
493  if (associated(generic)) then
494  select type(generic)
495  type is (field_ordering_type)
496  current_data_point=pack_scalar_field(byte_data, current_data_point, len(trim(map_entry%key)))
497  byte_data(current_data_point:current_data_point+len(trim(map_entry%key))-1) = transfer(trim(map_entry%key), &
498  byte_data(current_data_point:current_data_point+len(trim(map_entry%key))-1))
499  current_data_point=current_data_point+len(trim(map_entry%key))
500 
501  prev_pt=current_data_point
502  current_data_point=current_data_point+kind(current_data_point)
503  call serialise_specific_field_ordering(generic, byte_data, current_data_point)
504  prev_pt=pack_scalar_field(byte_data, prev_pt, (current_data_point-kind(current_data_point))-prev_pt)
505  end select
506  end if
507  end do
508 
509  call check_thread_status(forthread_rwlock_unlock(field_lock))
Here is the call graph for this function:
Here is the caller graph for this function:

◆ serialise_field_ordering_value()

subroutine writer_field_manager_mod::serialise_field_ordering_value ( type(field_ordering_value_type), intent(inout)  specific_field_value,
character, dimension(:), intent(inout), allocatable  byte_data,
integer, intent(inout)  current_data_point 
)
private

Serialises a field ordering value and releases any issued locks.

Parameters
specific_field_valueThe specific value to serialise
byte_dataTarget byte data whihc is allocated here
current_data_pointThe current write point in the byte data, is updated during call so represents next point on return

Definition at line 658 of file writer_field_manager.F90.

658  type(field_ordering_value_type), intent(inout) :: specific_field_value
659  character, dimension(:), allocatable, intent(inout) :: byte_data
660  integer, intent(inout) :: current_data_point
661 
662  integer :: prev_pt
663 
664  current_data_point=pack_scalar_field(byte_data, current_data_point, specific_field_value%timestep)
665  current_data_point=pack_scalar_field(byte_data, current_data_point, specific_field_value%frequency)
666  current_data_point=pack_scalar_field(byte_data, current_data_point, specific_field_value%source)
667  current_data_point=pack_scalar_field(byte_data, current_data_point, len(trim(specific_field_value%field_name)))
668  byte_data(current_data_point:current_data_point+len(trim(specific_field_value%field_name))-1) = &
669  transfer(trim(specific_field_value%field_name), byte_data(current_data_point:current_data_point+&
670  len(trim(specific_field_value%field_name))-1))
671  current_data_point=current_data_point+len(trim(specific_field_value%field_name))
672  current_data_point=pack_scalar_field(byte_data, current_data_point, len(trim(specific_field_value%field_namespace)))
673  byte_data(current_data_point:current_data_point+len(trim(specific_field_value%field_namespace))-1) = &
674  transfer(trim(specific_field_value%field_namespace), byte_data(current_data_point:current_data_point+&
675  len(trim(specific_field_value%field_namespace))-1))
676  current_data_point=current_data_point+len(trim(specific_field_value%field_namespace))
677  current_data_point=pack_scalar_field(byte_data, current_data_point, double_real_value=specific_field_value%time)
678 
679  prev_pt=current_data_point
680  current_data_point=current_data_point+kind(current_data_point)
681  call serialise_data_values_type(specific_field_value%field_values, byte_data, current_data_point)
682  prev_pt=pack_scalar_field(byte_data, prev_pt, (current_data_point-kind(current_data_point))-prev_pt)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ serialise_specific_field_ordering()

subroutine writer_field_manager_mod::serialise_specific_field_ordering ( type(field_ordering_type), intent(inout)  specific_field_ordering,
character, dimension(:), intent(inout), allocatable  byte_data,
integer, intent(inout)  current_data_point 
)
private

Serialises a specific fields ordering and releases any locks issued during preparation.

Parameters
specific_field_orderingThe field ordering to serialise
byte_dataByte data which contains the packaged state of the field ordering
current_data_pointThe current write point in the byte data, is updated during call so represents next point on return

Definition at line 572 of file writer_field_manager.F90.

572  type(field_ordering_type), intent(inout) :: specific_field_ordering
573  character, dimension(:), allocatable, intent(inout) :: byte_data
574  integer, intent(inout) :: current_data_point
575 
576  integer :: prev_pt
577  type(mapentry_type) :: map_entry
578  type(iterator_type) :: iterator
579  class(*), pointer :: generic
580 
581  current_data_point=pack_scalar_field(byte_data, current_data_point, specific_field_ordering%last_timestep_access)
582  current_data_point=pack_scalar_field(byte_data, current_data_point, specific_field_ordering%frequency)
583  current_data_point=pack_scalar_field(byte_data, current_data_point, c_size(specific_field_ordering%timestep_to_value))
584 
585  iterator=c_get_iterator(specific_field_ordering%timestep_to_value)
586  do while (c_has_next(iterator))
587  map_entry=c_next_mapentry(iterator)
588  generic=>c_get_generic(map_entry)
589  if (associated(generic)) then
590  select type(generic)
591  type is (field_ordering_value_type)
592  current_data_point=pack_scalar_field(byte_data, current_data_point, len(trim(map_entry%key)))
593  byte_data(current_data_point:current_data_point+len(trim(map_entry%key))-1) = transfer(trim(map_entry%key), &
594  byte_data(current_data_point:current_data_point+len(trim(map_entry%key))-1))
595  current_data_point=current_data_point+len(trim(map_entry%key))
596 
597  prev_pt=current_data_point
598  current_data_point=current_data_point+kind(current_data_point)
599  call serialise_field_ordering_value(generic, byte_data, current_data_point)
600  prev_pt=pack_scalar_field(byte_data, prev_pt, (current_data_point-kind(current_data_point))-prev_pt)
601  end select
602  end if
603  end do
604 
605  call check_thread_status(forthread_mutex_unlock(specific_field_ordering%access_mutex))
Here is the call graph for this function:
Here is the caller graph for this function:

◆ unserialise_field_manager_state()

subroutine writer_field_manager_mod::unserialise_field_manager_state ( character, dimension(:), intent(in)  byte_data)
private

Unserialses from some byte data into the state.

Parameters
byte_dataSerialised byte data to inflate and initialise from

Definition at line 515 of file writer_field_manager.F90.

515  character, dimension(:), intent(in) :: byte_data
516 
517  integer :: current_data_point, number_of_entries, i, byte_size, key_size
518  character(len=STRING_LENGTH) :: value_key
519  class(*), pointer :: generic
520 
521  current_data_point=1
522  number_of_entries=unpack_scalar_integer_from_bytedata(byte_data, current_data_point)
523 
524  if (number_of_entries .gt. 0) then
525  do i=1, number_of_entries
526  key_size=unpack_scalar_integer_from_bytedata(byte_data, current_data_point)
527  value_key=transfer(byte_data(current_data_point:current_data_point+key_size-1), value_key)
528  value_key(key_size+1:)=" "
529  current_data_point=current_data_point+key_size
530  byte_size=unpack_scalar_integer_from_bytedata(byte_data, current_data_point)
531  generic=>unserialise_specific_field_ordering(byte_data(current_data_point:current_data_point+byte_size-1))
532  call c_put_generic(field_orderings, value_key, generic, .false.)
533  current_data_point=current_data_point+byte_size
534  end do
535  end if
Here is the call graph for this function:
Here is the caller graph for this function:

◆ unserialise_field_ordering_value()

type(field_ordering_value_type) function, pointer writer_field_manager_mod::unserialise_field_ordering_value ( character, dimension(:), intent(in)  byte_data)
private

Unseralises some field ordering from its byte representation.

Parameters
byte_dataThe serialised representation
Returns
The corresponding initialised and completed ordering value

Definition at line 689 of file writer_field_manager.F90.

689  character, dimension(:), intent(in) :: byte_data
690  type(field_ordering_value_type), pointer :: unserialise_field_ordering_value
691 
692  integer :: current_data_point, byte_size, str_size
693 
694  allocate(unserialise_field_ordering_value)
695  current_data_point=1
696  unserialise_field_ordering_value%timestep=unpack_scalar_integer_from_bytedata(byte_data, current_data_point)
697  unserialise_field_ordering_value%frequency=unpack_scalar_integer_from_bytedata(byte_data, current_data_point)
698  unserialise_field_ordering_value%source=unpack_scalar_integer_from_bytedata(byte_data, current_data_point)
699  str_size=unpack_scalar_integer_from_bytedata(byte_data, current_data_point)
700  unserialise_field_ordering_value%field_name=transfer(byte_data(current_data_point:current_data_point+str_size-1), &
701  unserialise_field_ordering_value%field_name)
702  unserialise_field_ordering_value%field_name(str_size+1:)=" "
703  current_data_point=current_data_point+str_size
704  str_size=unpack_scalar_integer_from_bytedata(byte_data, current_data_point)
705  unserialise_field_ordering_value%field_namespace=transfer(byte_data(current_data_point:current_data_point+str_size-1), &
706  unserialise_field_ordering_value%field_namespace)
707  unserialise_field_ordering_value%field_namespace(str_size+1:)=" "
708  current_data_point=current_data_point+str_size
709  unserialise_field_ordering_value%time=unpack_scalar_dp_real_from_bytedata(byte_data, current_data_point)
710  byte_size=unpack_scalar_integer_from_bytedata(byte_data, current_data_point)
711  unserialise_field_ordering_value%field_values=unserialise_data_values_type(byte_data(current_data_point:&
712  current_data_point+byte_size-1))
Here is the call graph for this function:
Here is the caller graph for this function:

◆ unserialise_specific_field_ordering()

type(field_ordering_type) function, pointer writer_field_manager_mod::unserialise_specific_field_ordering ( character, dimension(:), intent(in)  byte_data)
private

Unserialises some field ordering.

Parameters
byte_dataThe serialised representation which we work from
Returns
The initialised field ordering represented by the provided byte data

Definition at line 612 of file writer_field_manager.F90.

612  character, dimension(:), intent(in) :: byte_data
613  type(field_ordering_type), pointer :: unserialise_specific_field_ordering
614 
615  integer :: current_data_point, number_of_values, byte_size, i, key_size
616  character(len=STRING_LENGTH) :: value_key
617  class(*), pointer :: generic
618 
619  allocate(unserialise_specific_field_ordering)
620 
621  current_data_point=1
622  unserialise_specific_field_ordering%last_timestep_access=unpack_scalar_integer_from_bytedata(byte_data, current_data_point)
623  unserialise_specific_field_ordering%frequency=unpack_scalar_integer_from_bytedata(byte_data, current_data_point)
624  number_of_values=unpack_scalar_integer_from_bytedata(byte_data, current_data_point)
625 
626  if (number_of_values .gt. 0) then
627  do i=1, number_of_values
628  key_size=unpack_scalar_integer_from_bytedata(byte_data, current_data_point)
629  value_key=transfer(byte_data(current_data_point:current_data_point+key_size-1), value_key)
630  value_key(key_size+1:)=" "
631  current_data_point=current_data_point+key_size
632  byte_size=unpack_scalar_integer_from_bytedata(byte_data, current_data_point)
633  generic=>unserialise_field_ordering_value(byte_data(current_data_point:current_data_point+byte_size-1))
634  call c_put_generic(unserialise_specific_field_ordering%timestep_to_value, value_key, generic, .false.)
635  current_data_point=current_data_point+byte_size
636  end do
637  end if
638  call check_thread_status(forthread_mutex_init(unserialise_specific_field_ordering%access_mutex, -1))
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ field_lock

integer, volatile writer_field_manager_mod::field_lock
private

Definition at line 48 of file writer_field_manager.F90.

48  integer, volatile :: field_lock

◆ field_orderings

type(hashmap_type), volatile writer_field_manager_mod::field_orderings
private

Definition at line 49 of file writer_field_manager.F90.

49  type(hashmap_type), volatile :: field_orderings