29 character(len=STRING_LENGTH) :: variable
65 source_monc, operator_result_values)
68 type(
map_type),
intent(inout) :: action_attributes
69 integer,
intent(in) :: source_monc_location, source_monc
70 real(kind=DEFAULT_PRECISION),
dimension(:),
allocatable,
intent(inout) :: operator_result_values
72 character(len=STRING_LENGTH) :: equation
78 if (.not.
associated(cached_equation%execution_tree))
then 82 allocate(operator_result_values(data_size))
97 integer :: temp_size, prev_size
100 if (.not.
c_is_empty(cached_equation%required_fields))
then 108 temp_size=
size(variable_data%values)
117 "Can only perform arithmetic on variables with the same array sizes or sizes that divide evenly")
134 integer,
intent(in) :: n
135 real(kind=DEFAULT_PRECISION),
dimension(n) :: result_value
137 real(kind=DEFAULT_PRECISION),
dimension(n) :: left_value, right_value
148 if (
size(variable_data%values) .lt. n)
then 149 do i=1, n,
size(variable_data%values)
150 result_value(i:i+
size(variable_data%values)-1)=variable_data%values
153 result_value=variable_data%values
159 if (equation_tree%operator ==
add_op)
then 160 result_value(:)=left_value(:)+right_value(:)
161 else if (equation_tree%operator ==
minus_op)
then 162 result_value(:)=left_value(:)-right_value(:)
163 else if (equation_tree%operator ==
mul_op)
then 164 result_value(:)=left_value(:)*right_value(:)
165 else if (equation_tree%operator ==
div_op)
then 166 result_value(:)=left_value(:)/right_value(:)
167 else if (equation_tree%operator ==
mod_op)
then 169 result_value(i)=mod(left_value(i), right_value(i))
183 character(len=*),
intent(in) :: equation
186 integer :: split_point
188 allocate(equation_tree)
190 if (split_point .gt. 0)
then 196 equation_tree%variable=equation
199 equation_tree%variable=trim(adjustl(equation_tree%variable))
200 if (equation_tree%variable(1:1) .eq.
"{" .and. &
201 equation_tree%variable(len_trim(equation_tree%variable):len_trim(equation_tree%variable)) .eq.
"}")
then 203 io_configuration%options_database, equation_tree%variable(2:len_trim(equation_tree%variable)-1)))
212 character(len=*),
intent(inout) :: raw_string
213 character,
intent(in) :: c
215 integer :: brace_index
217 brace_index=index(raw_string, c)
218 do while (brace_index .gt. 0)
219 raw_string(brace_index:brace_index)=
" " 220 brace_index=index(raw_string, c)
227 character(len=*),
intent(in) :: equation
229 integer :: i, eq_len, location_value, op, op_val, brace_level
232 location_value=999999
234 eq_len=len(trim(equation))
237 if (equation(i:i) ==
"(") brace_level=brace_level-1
238 if (equation(i:i) ==
")") brace_level=brace_level+1
242 if (op ==
div_op) op_val=4
243 if (op ==
mod_op) op_val=4
244 if (op ==
mul_op) op_val=3
245 if (op ==
add_op) op_val=2
247 op_val=op_val + (brace_level*10)
248 if (op_val .lt. location_value)
then 249 location_value=op_val
260 character,
intent(in) :: op_char
262 if (op_char .eq.
"/")
then 264 else if (op_char .eq.
"*")
then 266 else if (op_char .eq.
"-")
then 268 else if (op_char .eq.
"+")
then 270 else if (op_char .eq.
"%")
then 280 type(
list_type) function arithmetic_operator_get_required_fields(action_attributes)
283 character(len=STRING_LENGTH) :: equation
288 if (
c_is_empty(cached_equation%required_fields))
then 291 arithmetic_operator_get_required_fields=cached_equation%required_fields
298 type(list_type) function process_equation_to_get_required_fields(equation)
299 character(len=*),
intent(in) :: equation
301 character(len=STRING_LENGTH) :: str_to_write
303 integer :: i, eq_length, starting_len
305 eq_length=len(trim(equation))
310 if (c .eq.
"/" .or. c .eq.
"*" .or. c .eq.
"-" .or. c .eq.
"+" .or. c .eq.
"(" .or. c .eq.
")" .or. c .eq.
"%")
then 311 if (starting_len .lt. i)
then 312 str_to_write=equation(starting_len: i-1)
313 if (.not. (conv_is_real(str_to_write) .or. conv_is_integer(str_to_write) .or. str_to_write(1:1) .eq.
"{"))
then 320 if (starting_len .le. eq_length)
then 321 str_to_write=equation(starting_len: i-1)
322 if (.not. (conv_is_real(str_to_write) .or. conv_is_integer(str_to_write)))
then 333 character(len=*),
intent(in) :: equation
336 class(*),
pointer :: generic
339 if (.not.
associated(find_or_add_equation))
then 342 if (.not.
associated(find_or_add_equation))
then 343 allocate(find_or_add_equation)
344 find_or_add_equation%execution_tree=>null()
345 generic=>find_or_add_equation
357 character(len=*),
intent(in) :: equation
359 logical,
intent(in) :: dolock
361 class(*),
pointer :: generic
366 if (
associated(generic))
then 369 find_equation=>generic
372 find_equation=>null()
integer, parameter terminal_op
recursive real(kind=default_precision) function, dimension(n) execute_equation_tree(equation_tree, field_values, n)
Executes an equation tree by doing a post order traversal of the tree. If a node is a terminal then e...
integer function forthread_rwlock_init(rwlock_id, attr_id)
Gets a specific generic element out of the list, stack, queue or map with the corresponding key...
subroutine, public perform_arithmetic_operator(io_configuration, field_values, action_attributes, source_monc_location, source_monc, operator_result_values)
Executes this arithmetic operator by attempting to retrieved the cached equation (and creates one if ...
Returns whether a collection is empty.
Overall IO configuration.
type(hashmap_type), volatile equation_cache
integer, parameter minus_op
integer, parameter, public log_error
Only log ERROR messages.
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.
Contains functionality for managing and extracting data from the raw data dumps that the IO server re...
integer, parameter mod_op
A specific node in the execution tree.
The arithmetic operator which allows the user to define arithmetic formulas based on fields and const...
integer, parameter, public default_precision
MPI communication type which we use for the prognostic and calculation data.
subroutine remove_character(raw_string, c)
Removes all occurances of a character from a string in situ by replacing it with whitespace.
integer function forthread_rwlock_rdlock(lock_id)
Contains common definitions for the data and datatypes used by MONC.
subroutine, public initialise_arithmetic_operator()
Initialises this operator.
A hashmap structure, the same as a map but uses hashing for greatly improved performance when storing...
Conversion between common inbuilt FORTRAN data types.
Converts data types to strings.
integer function forthread_rwlock_wrlock(lock_id)
type(list_type) function process_equation_to_get_required_fields(equation)
Performs text processing on an equation to extract out all the required variable (fields) needed in o...
subroutine, public log_log(level, message, str)
Logs a message at the specified level. If the level is above the current level then the message is ig...
integer, parameter div_op
Map data structure that holds string (length 20 maximum) key value pairs.
This is a thread pool and the single management "main" thread will spawn out free threads in the pool...
subroutine, public check_thread_status(ierr)
Checks the error status of any thread operation and reports an error if it failed.
integer function get_operator_representation(op_char)
Given a character representation of an operator this returns the internal numeric type representation...
subroutine, public finalise_arithmetic_operator()
Finalises this opertor.
integer function get_size_of_data_being_operated_on(cached_equation, field_values)
Retrieves the number of data elements that this will operate on. It will produce a log error if any v...
Collection data structures.
type(arithmetic_cache_item) function, pointer find_equation(equation, dolock)
Finds an equation in the cache based upon its textual equation representation or returns null if none...
Determines whether a data item can be represented as an integer or not.
integer function get_location_of_least_significant_operator(equation)
Given an equation this will retrieve the location of the least significant operator in that equation ...
Converts data types to real.
integer, parameter, public string_length
Default length of strings.
character(len=string_length) function, public get_action_attribute_string(action_attributes, field_name)
Retrieves the name of a field from the attributes specified in the configuration. ...
type(list_type) function, public arithmetic_operator_get_required_fields(action_attributes)
Retrieves the list of fields needed by this operator for a specific configuration.
recursive type(arithmetic_execution_node) function, pointer build_equation_tree(io_configuration, equation)
Builds the equation tree, this searches for the least significant operator and then splits the equati...
List data structure which implements a doubly linked list. This list will preserve its order...
real(kind=default_precision) function, public options_get_real(options_database, key, index)
Retrieves a real value from the database that matches the provided key.
integer function forthread_rwlock_destroy(rwlock_id)
integer function, public options_get_integer(options_database, key, index)
Retrieves an integer value from the database that matches the provided key.
Determines whether a data item can be represented as a real or not.
integer, volatile equation_cache_rwlock
Manages the options database. Contains administration functions and deduce runtime options from the c...
integer function forthread_rwlock_unlock(lock_id)
Puts a generic key-value pair into the map.
integer, parameter add_op
type(arithmetic_cache_item) function, pointer find_or_add_equation(equation)
Locates an existing equation in the cache based upon the textual equation representation or creates a...
Converts data types to integers.
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.
Gets a specific string element out of the list, stack, queue or map with the corresponding key...
integer, parameter mul_op
Parses the XML configuration file to produce the io configuration description which contains the data...