Difference between revisions of "Code coupling in Kraken"

From Kraken Wiki
Jump to: navigation, search
(Type 1 — Structured regular Cartesian mesh)
(Basic "function calls")
 
(77 intermediate revisions by 3 users not shown)
Line 1: Line 1:
  
The code coupling in Kraken is based on a "hub and spoke" approach where each solver module only needs to communicate with the central multi-physics driver Cerberus. The Cerberus multi-physics driver is responsible for executing each solver module, exchanging field data with them and controlling the execution order of the different modules.
+
The code coupling in Kraken is based on a "hub and spoke" approach where each solver module only needs to communicate with the central multi-physics driver Cerberus. The Cerberus multi-physics driver is responsible for starting up each solver module, exchanging field data with them and controlling the execution order of the different modules.
  
 
The individual solver modules should implement basic signalling capabilities so that they can accept signals from Cerberus as well as send messages back using the signalling syntax described below.
 
The individual solver modules should implement basic signalling capabilities so that they can accept signals from Cerberus as well as send messages back using the signalling syntax described below.
Line 6: Line 6:
 
== Basics of signalling ==
 
== Basics of signalling ==
  
When the solver is executed from command line by Cerberus, the solver should read its own input, initialize the specified signalling mode via the specified greeting protocol.
+
When the solver is executed from command line by [[Cerberus]] when running a Python script such as
  
After the greeting and its own basic initialization, the solver should wait for further signals from Cerberus.  
+
# --- Initialize solvers
 +
 
 +
my_input = CodeInput("path_to_my_input")
 +
my_solver = Solver("my_solver_name", path_to_my_solver, ["--port",])
 +
my_solver.input = my_input
 +
my_solver.initialize()
 +
 
 +
Cerberus will provide the port the solver should connect to as a pair of command line arguments '''"--port" <port_as_integer>'''. The solver should then read its own input, do whatever processing is required and open a socket on the indicated port for communication with Cerberus.
 +
 
 +
After the port has been opened, Cerberus expects the following greeting process:
 +
 
 +
{|class="wikitable" style="text-align: left;"
 +
!Direction
 +
!Name
 +
!Size and type
 +
!Content
 +
|-
 +
| {{highlight|Solver|tomato}}->{{highlight|Cerberus|PaleGreen}}
 +
| Lgreet
 +
| 1*integer
 +
| Length of greeting string in char excluding terminating character
 +
|-
 +
| {{highlight|Solver|tomato}}->{{highlight|Cerberus|PaleGreen}}
 +
|
 +
| Lgreet*char
 +
| A freely chosen greeting string (will be read and can be printed out by Cerberus).
 +
|-
 +
| {{highlight|Cerberus|PaleGreen}}->{{highlight|Solver|tomato}}
 +
| Lgreet
 +
| 1*integer
 +
| Length of greeting string in char excluding terminating character
 +
|-
 +
| {{highlight|Cerberus|PaleGreen}}->{{highlight|Solver|tomato}}
 +
|
 +
| Lgreet*char
 +
| Some greeting string sent by Cerberus.
 +
|}
 +
 
 +
After the greeting and its own basic initialization, the solver should wait for further signals from Cerberus.  
  
 
After each order received from Cerberus, the solver should fulfill the order and wait for further signals from Cerberus.
 
After each order received from Cerberus, the solver should fulfill the order and wait for further signals from Cerberus.
Line 18: Line 56:
 
When the solvers have completed their previous order and are waiting for the next signal from Cerberus, Cerberus will initiate the communication with a single integer indicating which "function call" should be processed.   
 
When the solvers have completed their previous order and are waiting for the next signal from Cerberus, Cerberus will initiate the communication with a single integer indicating which "function call" should be processed.   
  
The function calls that should be supported by the solvers are:  
+
The function calls and the integers representing them in the communication syntax are listed in a table below. When coupling a solver to Cerberus, they are typically listed in some centrally located header (or some such) files for C and Fortran. These can be also checked from [https://serpent.vtt.fi/pythonapi/generated/cerberus.commons.KrakenSignals.html cerberus.commons.KrakenSignals].
  
*'''terminate'''
+
{|class="wikitable" style="text-align: left;"
*'''giveInputFieldTemplates'''
+
!Function name
*'''giveOutputFieldTemplates'''
+
!Integer value
*'''giveFieldData'''
+
|-
*'''takeFieldData'''
+
| terminate
*'''giveOutputVariableDefs'''
+
| 0
*'''giveOutputVariableData'''
+
|-
*'''giveInputVariableDefs'''
+
| returnCurrentTime
*'''takeVariableData'''
+
| 1
*'''solveSteadyState'''
+
|-
*'''returnPresentTime'''
+
| setCurrentTime
*'''suggestNextTime'''
+
| 2
*'''advanceToTime'''
+
|-
*'''solveCurrentTime'''
+
| suggestNextTime
 
+
| 3
Each of these function calls corresponds to a certain integer, that are listed in some centrally located header (or some such) files for C and Fortran.
+
|-
 +
| advanceToTime
 +
| 4
 +
|-
 +
| solveCurrentTime
 +
| 5
 +
|-
 +
| giveInputFieldNames
 +
| 6
 +
|-
 +
| giveOutputFieldNames
 +
| 7
 +
|-
 +
| giveFieldTemplate
 +
| 8
 +
|-
 +
| giveMeshData
 +
| 9
 +
|-
 +
| giveIndexingArray
 +
| 10
 +
|-
 +
| giveFieldData
 +
| 11
 +
|-
 +
| takeFieldData
 +
| 12
 +
|-
 +
| giveOutputVariableDefs
 +
| 13
 +
|-
 +
| giveVariableData
 +
| 14
 +
|-
 +
| giveInputVariableDefs
 +
| 15
 +
|-
 +
| takeVariableData
 +
| 16
 +
|-
 +
| writeRestart
 +
| 17
 +
|-
 +
| readRestart
 +
| 18
 +
|-
 +
| returnCurrentTimeInterval
 +
| 19
 +
|-
 +
| setCurrentTimeInterval
 +
| 20
 +
|-
 +
| suggestNextTimeInterval
 +
| 21
 +
|-
 +
| advanceToTimeInterval
 +
| 22
 +
|-
 +
| correctPreviousStep
 +
| 23
 +
|}
  
 
The following sections will go through the signalling for each of the function calls  
 
The following sections will go through the signalling for each of the function calls  
Line 45: Line 143:
 
No further signalling takes place after the {{highlight|C|PaleGreen}}->{{highlight|S|tomato}} signal to terminate.
 
No further signalling takes place after the {{highlight|C|PaleGreen}}->{{highlight|S|tomato}} signal to terminate.
  
=== giveInputFieldTemplates ===
+
=== giveInputFieldNames ===
  
The solver should communicate, which sorts of fields it is expecting to receive from Cerberus. The communication syntax is as follows:  
+
The solver should communicate the names of the fields it is expecting to receive from Cerberus. The communication syntax is as follows:  
  
 
{|class="wikitable" style="text-align: left;"
 
{|class="wikitable" style="text-align: left;"
Line 57: Line 155:
 
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}
 
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}
 
| NF  
 
| NF  
| 1*integer  
+
| 1*integer  
 
| Number of fields to be provided  
 
| Number of fields to be provided  
 
|-
 
|-
Line 73: Line 171:
 
|
 
|
 
| Lname*char  
 
| Lname*char  
| Name of the field  
+
| Name of the field
 +
|}
 +
 
 +
=== giveOutputFieldNames  ===
 +
 
 +
The solver should communicate the names of the fields it is expecting to provide to Cerberus. The communication syntax is as follows:
 +
 
 +
{|class="wikitable" style="text-align: left;"
 +
!Direction
 +
!Name
 +
!Size and type
 +
!Content
 +
|-
 +
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}
 +
| NF
 +
| 1*integer
 +
| Number of fields to be provided
 +
|-
 +
| The following repeats  NF times:
 +
|
 +
|
 +
|
 +
|-
 +
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}
 +
| Lname
 +
| 1*integer
 +
| Length of field name in char excluding terminating character
 +
|-
 +
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}
 +
|
 +
| Lname*char
 +
| Name of the field
 +
|}
 +
 
 +
=== giveFieldTemplate ===
 +
 
 +
The solver should provide basic information on the field requested by Cerberus.
 +
 
 +
The communication syntax is as follows:
 +
 
 +
{|class="wikitable" style="text-align: left;"
 +
!Direction
 +
!Name
 +
!Size and type
 +
!Content
 +
|-
 +
| {{highlight|C|PaleGreen}}->{{highlight|S|tomato}}
 +
| LnameF
 +
| 1*integer
 +
| Length of name of requested field (in char excluding terminating character).
 +
|-
 +
| {{highlight|C|PaleGreen}}->{{highlight|S|tomato}}
 +
|
 +
| LnameF*char
 +
| Name of the requested field
 +
|-
 +
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}
 +
|
 +
| 1*integer
 +
| Data type (FLOAT = '''1''', INT = '''2''', STRING = '''3''')
 
|-
 
|-
 
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}  
 
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}  
Line 83: Line 240:
 
|
 
|
 
| 1*float  
 
| 1*float  
| Multiplier used to convert from the base unit type specified by the unit array to the actual unit used by the solver.
+
| Multiplier ''a'' used to convert from the base unit type specified by the unit array to the actual unit used by the solver (a*x + b).
 +
|-
 +
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}
 +
|
 +
| 1*float
 +
| Offset ''b'' used to convert from the base unit type specified by the unit array to the actual unit used by the solver (a*x + b).
 
|-
 
|-
 
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}
 
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}
|
+
| LnameM
 
| 1*integer  
 
| 1*integer  
| Type of the mesh that the field is on (see [[Code coupling in Kraken#Mesh types|Mesh types]]).
+
| Length of mesh name in char excluding terminating character
 
|-
 
|-
 
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}
 
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}
 
|
 
|
| <depends on mesh>
+
| LnameM*char
| Mesh data, see subsection Mesh types
+
| Name of the mesh
 
|-
 
|-
 
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}
 
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}
 
|
 
|
 
| 1*integer  
 
| 1*integer  
| Indexing flag: '''0''' if solver uses the default indexing of the mesh. '''1''' if solver uses some other indexing.  
+
| Indexing flag: '''0''' if solver uses the default indexing of the mesh. '''1''' if solver uses some other indexing: [[Mesh types#Indexing array|Indexing array]]
 +
|-
 +
| [{{highlight|S|tomato}}->{{highlight|C|PaleGreen}}]
 +
| LnameI
 +
| 1*integer
 +
| Only if  indexing flag was given as '''1''' (use custom indexing). Length of indexing array name in char excluding terminating character.  
 
|-
 
|-
 
| [{{highlight|S|tomato}}->{{highlight|C|PaleGreen}}]
 
| [{{highlight|S|tomato}}->{{highlight|C|PaleGreen}}]
 
|
 
|
| [number of cells in the mesh]
+
| LnameI*char
| Only if  indexing flag was given as '''1''' (use custom indexing): [[#Indexing information|Indexing information]]
+
| Only if  indexing flag was given as '''1''' (use custom indexing). Name of the indexing array.
 
|}
 
|}
  
After the solver has finished sending data to Cerberus, it should wait for further signals from Cerberus.
+
=== giveMeshData ===
  
=== giveOutputFieldTemplates  ===
+
The solver should provide information on the mesh requested by Cerberus.
  
The solver should communicate, which sorts of fields it is expecting to provide to Cerberus. The communication syntax is as follows:  
+
The communication syntax is as follows:  
  
 
{|class="wikitable" style="text-align: left;"
 
{|class="wikitable" style="text-align: left;"
Line 118: Line 285:
 
!Content  
 
!Content  
 
|-
 
|-
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}
+
| {{highlight|C|PaleGreen}}->{{highlight|S|tomato}}
| NF
 
| 1*integer
 
| Number of fields to be provided
 
|-
 
| The following repeats  NF times:
 
|
 
|
 
|
 
|-
 
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}
 
 
| Lname  
 
| Lname  
 
| 1*integer  
 
| 1*integer  
| Length of field name in char excluding terminating character  
+
| Length of name of requested mesh (in char excluding terminating character).
 
|-
 
|-
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}
+
| {{highlight|C|PaleGreen}}->{{highlight|S|tomato}}
 
|
 
|
 
| Lname*char  
 
| Lname*char  
| Name of the field
+
| Name of the requested mesh
|-
 
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}
 
|
 
| 5*integer
 
| Unit of the field in an OpenFOAMish array (see [[Code coupling in Kraken#Field unit array|Field unit array]])
 
|-
 
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}
 
|
 
| 1*float
 
| Multiplier used to convert from the base unit type specified by the unit array to the actual unit used by the solver: (SI unit) * (multiplier) = solver unit
 
 
|-
 
|-
 
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}
 
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}
 
|
 
|
 
| 1*integer  
 
| 1*integer  
| Type of the mesh that the field is on (see [[Code coupling in Kraken#Mesh types|Mesh types]]).  
+
| Type of the mesh (see [[Mesh types]]).  
 
|-
 
|-
 
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}
 
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}
Line 157: Line 304:
 
| <depends on mesh>  
 
| <depends on mesh>  
 
| Mesh data, see subsection Mesh types  
 
| Mesh data, see subsection Mesh types  
 +
|}
 +
 +
=== giveIndexingArray ===
 +
 +
The solver should provide information on the indexing array requested by Cerberus.
 +
 +
The communication syntax is as follows:
 +
 +
{|class="wikitable" style="text-align: left;"
 +
!Direction
 +
!Name
 +
!Size and type
 +
!Content
 +
|-
 +
| {{highlight|C|PaleGreen}}->{{highlight|S|tomato}}
 +
| Lname
 +
| 1*integer
 +
| Length of name of requested indexing array (in char excluding terminating character).
 
|-
 
|-
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}
+
| {{highlight|C|PaleGreen}}->{{highlight|S|tomato}}
 
|
 
|
 +
| Lname*char
 +
| Name of the requested indexing array
 +
|-
 +
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}
 +
| NV
 
| 1*integer  
 
| 1*integer  
| Indexing flag: '''0''' if solver uses the default indexing of the mesh. '''1''' if solver uses some other indexing.  
+
| Number of values to be passed.
 
|-
 
|-
| [{{highlight|S|tomato}}->{{highlight|C|PaleGreen}}]
+
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}  
 
|
 
|
| [number of cells in the mesh]
+
| NV*value
| Only if  indexing flag was given as '''1''' (use custom indexing): [[#Indexing information|Indexing information]]
+
| Indices: [[Mesh types#Indexing array|Indexing array]]
 
|}
 
|}
 
After the solver has finished sending data to Cerberus, it should wait for further signals from Cerberus.
 
  
 
=== giveFieldData ===
 
=== giveFieldData ===
Line 200: Line 368:
 
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}  
 
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}  
 
|
 
|
| NV*float
+
| NV*value
| The values for the field.
+
| The values for the field (float, integer or strings).
 
|}
 
|}
 
After the solver has finished passing data to Cerberus, it should wait for further signals from Cerberus.
 
  
 
=== takeFieldData ===
 
=== takeFieldData ===
Line 235: Line 401:
 
| {{highlight|C|PaleGreen}}->{{highlight|S|tomato}}
 
| {{highlight|C|PaleGreen}}->{{highlight|S|tomato}}
 
|
 
|
| NV*float
+
| NV*value
| The values for the field.
+
| The values for the field (float, integer or strings).
 
|}
 
|}
 
After the solver has finished receiving data from Cerberus, it should wait for further signals from Cerberus.
 
  
 
=== giveOutputVariableDefs  ===
 
=== giveOutputVariableDefs  ===
Line 271: Line 435:
 
| Name of the variable to be passed
 
| Name of the variable to be passed
 
|-
 
|-
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}  
+
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}
 
|
 
|
 
| 1*integer  
 
| 1*integer  
| Statistics flag: '''1''' if solver will provide mean values along with relative errors (Seprent). '''0''' if solver will only provide values (deterministic solvers).
+
| Data type (FLOAT = '''1''', INT = '''2''', STRING = '''3''')  
 
|-
 
|-
 
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}  
 
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}  
Line 282: Line 446:
 
|}
 
|}
  
After the solver has finished sending data to Cerberus, it should wait for further signals from Cerberus.
+
=== giveVariableData ===
 
 
=== giveOutputVariableData ===
 
  
 
The solver should provide the variable requested by Cerberus.
 
The solver should provide the variable requested by Cerberus.
Line 305: Line 467:
 
| Lname*char  
 
| Lname*char  
 
| Name of the variable to be passed
 
| Name of the variable to be passed
|-
 
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}
 
|
 
| 1*integer
 
| Statistics flag: '''1''' if solver will provide mean values along with relative errors (Seprent). '''0''' if solver will only provide values (deterministic solvers).
 
 
|-
 
|-
 
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}  
 
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}  
Line 318: Line 475:
 
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}  
 
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}  
 
|
 
|
| NV*float
+
| NV*value
| Variable values.
+
| Variable values (float, integer or strings).
 
|-
 
|-
 
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}  
 
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}  
Line 326: Line 483:
 
| Only if statistics flag was given as '''1'''. Relative errors.
 
| Only if statistics flag was given as '''1'''. Relative errors.
 
|}
 
|}
 
After the solver has finished passing data to Cerberus, it should wait for further signals from Cerberus.
 
  
 
=== giveInputVariableDefs  ===
 
=== giveInputVariableDefs  ===
Line 359: Line 514:
 
| Name of the variable to be passed
 
| Name of the variable to be passed
 
|-
 
|-
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}  
+
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}
 
|
 
|
 
| 1*integer  
 
| 1*integer  
| Variable type. Supported values: 0 (transformation) and 1 (miscellaneous).
+
| Data type (FLOAT = '''1''', INT = '''2''', STRING = '''3''')  
 
|-
 
|-
 
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}  
 
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}  
Line 369: Line 524:
 
| Number of values to be passed.
 
| Number of values to be passed.
 
|}
 
|}
 
After the solver has finished sending data to Cerberus, it should wait for further signals from Cerberus.
 
  
 
=== takeVariableData ===
 
=== takeVariableData ===
Line 393: Line 546:
 
| Lname*char  
 
| Lname*char  
 
| Name of the variable to be passed
 
| Name of the variable to be passed
|-
 
| {{highlight|C|PaleGreen}}->{{highlight|S|tomato}}
 
|
 
| 1*integer
 
| Variable type. Supported values: 0 (transformation) and 1 (miscellaneous).
 
 
|-
 
|-
 
| {{highlight|C|PaleGreen}}->{{highlight|S|tomato}}
 
| {{highlight|C|PaleGreen}}->{{highlight|S|tomato}}
Line 406: Line 554:
 
| {{highlight|C|PaleGreen}}->{{highlight|S|tomato}}
 
| {{highlight|C|PaleGreen}}->{{highlight|S|tomato}}
 
|
 
|
| NV*float
+
| NV*value
| The values for the variable.
+
| Variable values (float, integer or strings).
 
|}
 
|}
  
After the solver has finished receiving data from Cerberus, it should wait for further signals from Cerberus.
+
=== returnCurrentTime  ===
  
=== solveSteadyState ===
+
The solver should return the time corresponding to the current time point as a float in seconds. This can be used to check that all solvers proceed at the same time points in burnup calculations.
  
The solver should simply execute the next steady state solution using the current input fields.
+
{|class="wikitable" style="text-align: left;"
 +
!Direction
 +
!Name
 +
!Size and type
 +
!Content
 +
|-
 +
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}
 +
| t1
 +
| 1*float
 +
| Current time point of the solver (seconds).
 +
|}
  
After the solver has finished the steady state solution, it should wait for further signals from Cerberus.
+
=== setCurrentTime  ===
  
=== returnPresentTime  ===
+
This method is usually called in the beginning of burnup calculations to set the starting time of the simulation. The solver should store the received time (a float in seconds) as the current time point and conduct any additional processing required.
  
The solver should return the time corresponding to the current time point as a float ''Unit?''.
+
{|class="wikitable" style="text-align: left;"
 
+
!Direction
After the {{highlight|S|tomato}}->{{highlight|C|PaleGreen}} communication of the value. The solver should wait for further signals from Cerberus.
+
!Name
 +
!Size and type
 +
!Content
 +
|-
 +
| {{highlight|C|PaleGreen}}->{{highlight|S|tomato}}
 +
| t1
 +
| 1*float
 +
| Time point to be set (seconds).
 +
|}
  
 
=== suggestNextTime  ===
 
=== suggestNextTime  ===
  
The solver should return a preferred length for the next time point (end of next timestep) as a float ''Unit?''.  
+
The solver should return a preferred length for the next time point (end of next timestep) as a float in seconds.  
  
After the {{highlight|S|tomato}}->{{highlight|C|PaleGreen}} communication of the value. The solver should wait for further signals from Cerberus.
+
{|class="wikitable" style="text-align: left;"
 +
!Direction
 +
!Name
 +
!Size and type
 +
!Content
 +
|-
 +
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}
 +
| t1
 +
| 1*float
 +
| Suggested next time point (seconds).
 +
|}
  
 
=== advanceToTime  ===
 
=== advanceToTime  ===
  
The solver should advance to the next time point (time step), with the given value ''Unit?''. This process may involve storing final results for the previous time point (time step), time integration of some data forwards to the next time point (e.g. burnup accumulation) etc.  
+
The solver should advance to the next time point (time step), with the given value in seconds. This process may involve storing final results for the previous time point (time step), time integration of some data forwards to the next time point (e.g. burnup accumulation) etc.  
  
After the {{highlight|C|PaleGreen}}->{{highlight|S|tomato}} communication of the value and the calls by the solver to the required internal routines the solver should wait for further signals from Cerberus.
+
{|class="wikitable" style="text-align: left;"
 
+
!Direction
=== solveCurrentTime  ===
+
!Name
 
+
!Size and type
The solver should execute the solution for the current time point (time step). This can include some initialization and post-processing for the current solution if needed.  
+
!Content
 
+
|-
After the solution has completed. The solver should wait for further signals from Cerberus.
+
| {{highlight|C|PaleGreen}}->{{highlight|S|tomato}}
 +
| t1
 +
| 1*float
 +
| Next time point (seconds).
 +
|}
  
== Field unit array ==
+
=== returnCurrentTimeInterval  ===
  
The field unit array consists of 5 integers (e.g. <tt>&#160;1 -3 &#160;0 &#160;0 &#160;0</tt> for mass density) specifying the dimension for each of the 5 SI base units for the field
+
The solver should provide information on the time interval it is currently solving to Cerberus (used in '''transient calculations'''):
  
 
{|class="wikitable" style="text-align: left;"
 
{|class="wikitable" style="text-align: left;"
! No.
+
!Direction
! Property
+
!Name
! Unit
+
!Size and type
 +
!Content
 
|-
 
|-
| 1
+
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}
| Mass
+
| t0
| kilogram (kg)  
+
| 1*float
 +
| Beginning time of current interval (seconds).
 
|-
 
|-
| 2
+
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}
| Length
+
| t1
| metre (m)
+
| 1*float
|-
+
| End time of current interval (seconds).
| 3
 
| Time
 
| second (s)
 
|-
 
| 4
 
| Temperature
 
| Kelvin (K)
 
|-
 
| 5
 
| Quantity
 
| mole (mol)  
 
 
|}
 
|}
  
This means that some of the basic fields that we might transfer will have types of
+
=== setCurrentTimeInterval  ===
 +
 
 +
Cerberus provides the solver information on the time interval to be solved and the solver should adjust itself accordingly (used in '''transient calculations'''):
  
 
{|class="wikitable" style="text-align: left;"
 
{|class="wikitable" style="text-align: left;"
! Field name
+
!Direction
! SI unit
+
!Name
! Basic unit
+
!Size and type
! Unit array
+
!Content
 
|-
 
|-
| Mass density
+
| {{highlight|C|PaleGreen}}->{{highlight|S|tomato}}
| kg/m3
+
| t0
| kg*m-3
+
| 1*float
| <tt>&#160;1 -3 &#160;0 &#160;0 &#160;0</tt>
+
| Beginning time of current interval (seconds).
 
|-
 
|-
| Temperature
+
| {{highlight|C|PaleGreen}}->{{highlight|S|tomato}}
| K
+
| t1
| K
+
| 1*float
| <tt>&#160;0 &#160;0 &#160;0 &#160;1 &#160;0</tt>
+
| End time of current interval (seconds).
|-
 
| Power (integral)
 
| W
 
| kg*m2*s-3
 
| <tt>&#160;1 &#160;2 -3 &#160;0 &#160;0</tt>  
 
|-
 
| Power density
 
| W/m3
 
| kg*m-1*s-3
 
| <tt>&#160;1 -1 -3 &#160;0 &#160;0</tt>
 
 
|}
 
|}
  
== Mesh types ==
+
=== suggestNextTimeInterval  ===
Each physical data field consists of values on a specific mesh. Whereas several mesh types should be supported by Cerberus, the individual solvers typically only need to support their own mesh types. This section describes the geometry of the different mesh types supported by Cerberus and the mesh-data (the ordered list of values exactly specifying the mesh) associated with each mesh type.
 
 
 
=== Type 1 &mdash; Structured regular Cartesian mesh ===
 
 
 
Structured regular Cartesian meshes (in Kraken) are 3D meshes that cover a cuboid volume ([x<sub>min</sub>, x<sub>max</sub>]*[y<sub>min</sub>, y<sub>max</sub>]*[z<sub>min</sub>, z<sub>max</sub>]) and have a fixed number of cells in the x-, y- and z-direction (N<sub>x</sub>, N<sub>y</sub>, N<sub>z</sub>). The total number of cells is the product of the number of cells in each of the three coordinate directions. The size/spacing of the cells is constant, but can be different for the different directions.
 
  
The mesh data for structured Cartesian meshes is as follows
+
The solver should provide its suggestion for the next time interval to be solved (used in '''transient calculations'''):
  
 
{|class="wikitable" style="text-align: left;"
 
{|class="wikitable" style="text-align: left;"
! Data type/size
+
!Direction
! Data content (explanation)
+
!Name
! Data content (example)
+
!Size and type
! Notes
+
!Content
 
|-
 
|-
| 1*integer
+
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}
| Mesh type
+
| t0
| '''1'''
+
| 1*float
|
+
| Suggested beginning time of next time interval (seconds).
 
|-
 
|-
|
+
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}
| ''Information on mesh size''
+
| t1
|
+
| 1*float
|
+
| Suggested end time of next time interval (seconds).
|-
 
| 1*integer
 
| N<sub>x</sub>
 
| '''2'''
 
| Number of cells in X-direction.
 
|-
 
| 1*integer
 
| N<sub>y</sub>
 
| '''1'''
 
| Number of cells in Y-direction.
 
|-
 
| 1*integer
 
| N<sub>z</sub>
 
| '''4'''
 
| Number of cells in Z-direction.
 
|-
 
|
 
| ''Information on mesh boundaries''
 
|
 
|
 
|-
 
| 2*float
 
| x<sub>min</sub>, x<sub>max</sub>
 
| '''-10.0''', '''10.0'''
 
| The outer limits of the mesh.
 
|-
 
|
 
|
 
|
 
|
 
|-
 
| 2*float
 
| y<sub>min</sub>, y<sub>max</sub>
 
| '''-5.0''', '''5.0'''
 
| The outer limits of the mesh.
 
|-
 
|
 
|
 
|
 
|
 
|-
 
| 2*float
 
| z<sub>min</sub>, z<sub>max</sub>
 
| '''0.0''', '''100.0'''
 
| The outer limits of the mesh.
 
 
|}
 
|}
  
==== Default indexing ====
+
The beginning time of the next time interval should be equal to the end time of the current time interval.
 
 
x runs fastest, then y and finally z slowest.
 
 
 
All indices increase from minimum coordinate to maximum coordinate.
 
 
 
=== Type 2 &mdash; Structured irregular Cartesian mesh ===
 
  
Structured Cartesian meshes (in Kraken) are 3D meshes that cover a cuboid volume ([x<sub>min</sub>, x<sub>max</sub>]*[y<sub>min</sub>, y<sub>max</sub>]*[z<sub>min</sub>, z<sub>max</sub>]) and have a fixed number of cells in the x-, y- and z-direction (N<sub>x</sub>, N<sub>y</sub>, N<sub>z</sub>). The total number of cells is the product of the number of cells in each of the three coordinate directions. For the irregular version, the size/spacing of the cells need not be constant.
+
=== advanceToTimeInterval  ===
  
The mesh data for structured irregular Cartesian meshes is as follows
+
Cerberus provides the solver information on the next time interval to be solved. The solver should prepare itself for solving the new time interval next (e.g. by setting the end-of-interval data of the previous time-interval to be used as beginning-of-interval data for the upcoming one). Used in '''transient calculations'''.
  
 
{|class="wikitable" style="text-align: left;"
 
{|class="wikitable" style="text-align: left;"
! Data type/size
+
!Direction
! Data content (explanation)
+
!Name
! Data content (example)
+
!Size and type
! Notes
+
!Content
 
|-
 
|-
| 1*integer
+
| {{highlight|C|PaleGreen}}->{{highlight|S|tomato}}
| Mesh type
+
| t0
| '''2'''
+
| 1*float
|
+
| Beginning time of the next time interval (seconds).
 
|-
 
|-
|
+
| {{highlight|C|PaleGreen}}->{{highlight|S|tomato}}
| ''Information on mesh size''
+
| t1
|
+
| 1*float
|
+
| End time of the next time interval (seconds).
|-
 
| 1*integer
 
| N<sub>x</sub>
 
| '''2'''
 
| Number of cells in X-direction.
 
|-
 
| 1*integer
 
| N<sub>y</sub>
 
| '''1'''
 
| Number of cells in Y-direction.
 
|-
 
| 1*integer
 
| N<sub>z</sub>
 
| '''4'''
 
| Number of cells in Z-direction.
 
|-
 
|
 
| ''Information on mesh boundaries''
 
|
 
|
 
|-
 
| (N<sub>x</sub>+1)*float
 
| x<sub>0</sub>, x<sub>1</sub>, ..., x<sub>N<sub>x</sub>+1</sub>
 
| '''-10.0''', '''-5.0''', '''10.0'''
 
| The cell boundaries in X-direction.
 
|-
 
|
 
|
 
|
 
|
 
|-
 
| (N<sub>y</sub>+1)*float
 
| y<sub>0</sub>, y<sub>1</sub>, ..., y<sub>N<sub>y</sub>+1</sub>
 
| '''-5.0''', '''5.0'''
 
| The cell boundaries in Y-direction.
 
|-
 
|
 
|
 
|
 
|
 
|-
 
| (N<sub>z</sub>+1)*float
 
| z<sub>0</sub>, z<sub>1</sub>, ..., z<sub>N<sub>z</sub>+1</sub>
 
| '''0.0''', '''35.0''', '''50.0''', '''65.0''', '''100.0'''
 
| The cell boundaries in Z-direction.
 
 
|}
 
|}
  
==== Default indexing ====
+
The beginning time of the next interval is more or less guaranteed to be the end time of the current interval.
  
x runs fastest, then y and finally z slowest.
+
=== solveCurrentTime  ===
  
All indices increase from minimum coordinate to maximum coordinate.
+
The solver should execute the solution for the current time point (time step). This can include some initialization and post-processing for the current solution if needed.
 
 
=== Types 3-6 &mdash; Structured hexagonal meshes ===
 
 
 
Four different hexagonal meshes are currently supported (types 3-6). The different mesh types correspond to different orientations of the hexagons and to different choices of basis vectors.
 
 
 
The mesh data for all structured hexagonal meshes is the same:
 
  
 +
After the solution has completed, the solver should send Cerberus an integer value indicating that the solution has been completed and to give some information on the potential convergence of the solution (as judged by the solver):
 
{|class="wikitable" style="text-align: left;"
 
{|class="wikitable" style="text-align: left;"
! Data type/size
+
!Direction
! Data content (explanation)
+
!Name
! Data content (example)
+
!Size and type
! Notes
+
!Content
 
|-
 
|-
| 1*integer
+
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}}
| Mesh type
+
| NV
| '''3'''
+
| 1*integer  
|
+
| A single integer 1, 2 or 3 (see below)
 
|-
 
|-
|
+
|  
| ''Information on mesh size''
+
|  
|
+
|  
|
+
| 1 = solution complete
 
|-
 
|-
| 1*integer
 
| N<sub>x</sub>
 
| '''4'''
 
 
|  
 
|  
 +
|
 +
|
 +
| 2 = solution complete and convergence reached
 
|-
 
|-
| 1*integer
 
| N<sub>y</sub>
 
| '''4'''
 
 
|  
 
|  
|-
 
| 1*integer
 
| N<sub>z</sub>
 
| '''4'''
 
 
|  
 
|  
|-
+
|  
|
+
| 3 = solution complete but diverged or other problems
| ''Information on horizontal mesh geometry''
 
|
 
|
 
|-
 
| 2*float
 
| x<sub>0</sub>, y<sub>0</sub>
 
| '''0.0''', '''0.0'''
 
| The horizontal centerpoint of the mesh.
 
|-
 
| 1*float
 
| pitch
 
| '''0.236'''
 
| The horizontal pitch between adjacent mesh cells.
 
|-
 
|
 
| ''Information on axial boundaries''
 
|
 
|-
 
| (N<sub>z</sub>+1)*float
 
| z<sub>0</sub>, z<sub>1</sub>, ..., z<sub>N<sub>z</sub>+1</sub>
 
| '''0.0''', '''0.35''', '''0.50''', '''0.65''', '''1.0'''
 
| The cell boundaries in Z-direction.
 
 
|}
 
|}
  
 +
=== correctPreviousStep ===
  
The following subsections show the base indexing in the different mesh types.
+
The solver may consider the current coupled solution converged and use this information to correct the previous time-integral that took the solver to the current time/time interval. If the solver cannot correct its previous time-integration or does not deem it necessary, it can simply ignore the signal.
  
==== Type 3 &mdash; Structured x-type 60 degree hexagonal mesh ====
+
Intended especially for burnup calculations but might be useful in some transient simulations also.
  
A single axial layer of the x-type (pointy top) hexagonal mesh with a 60 degree angle between the basis vectors is shown here:
+
=== writeRestart ===
  
[[File:hexx60.png|frameless|350px|Indexing in a single layer of a structured x-type 60 degree hexagonal mesh.]]
+
The solver should write its current state as a restart file. The path to the restart file may be fixed, given as a part of the solver input or as an input variable through Cerberus.  
  
==== Type 4 &mdash; Structured y-type 60 degree hexagonal mesh ====
+
The contents of the restart file can be freely chosen by the developer and may be context dependent, e.g. on the simulation type that is being executed (stationary, burnup, transient etc.)
  
A single axial layer of the y-type (flat top) hexagonal mesh with a 60 degree angle between the basis vectors is shown here:
+
=== readRestart ===
  
[[File:hexy60.png|frameless|225px|Indexing in a single layer of a structured y-type 60 degree hexagonal mesh.]]
+
The solver should set its internal state based on a restart file. The path to the restart file may be fixed, given as a part of the solver input or as an input variable through Cerberus.  
  
==== Type 5 &mdash; Structured x-type 120 degree hexagonal mesh ====
+
Along with the [[#writeRestart|writeRestart]] method, this one should allow e.g. for initializing a transient simulation based on a stationary state or continuing a previous calculation in another manner. The exact functionality can be chosen by the developer.
  
A single axial layer of the x-type (pointy top) hexagonal mesh with a 120 degree angle between the basis vectors is shown here:
+
== Field unit array ==
  
[[File:hexx120.png|frameless|350px|Indexing in a single layer of a structured x-type 120 degree hexagonal mesh.]]
+
The field unit array consists of 5 integers (e.g. <tt>&#160;1 -3 &#160;0 &#160;0 &#160;0</tt> for mass density) specifying the dimension for each of the 5 SI base units for the field
 
 
==== Type 6 &mdash; Structured y-type 120 degree hexagonal mesh ====
 
 
 
A single axial layer of the y-type (flat top) hexagonal mesh with a 120 degree angle between the basis vectors is shown here:
 
 
 
[[File:hexy120.png|frameless|250px|Indexing in a single layer of a structured y-type 120 degree hexagonal mesh.]]
 
 
 
=== Type 7 &mdash; Structured cylindrical mesh ===
 
 
 
The mesh data for structured cylindrical meshes is as follows
 
  
 
{|class="wikitable" style="text-align: left;"
 
{|class="wikitable" style="text-align: left;"
! Data type/size
+
! No.
! Data content (explanation)
+
! Property
! Data content (example)
+
! Unit
! Notes
 
 
|-
 
|-
| 1*integer
+
| 1  
| Mesh type
+
| Mass
| '''7'''
+
| kilogram (kg)
|
 
 
|-
 
|-
|
+
| 2
| ''Information on mesh size''
+
| Length
|
+
| metre (m)
|
 
 
|-
 
|-
| 1*integer
+
| 3
| N<sub>r</sub>
+
| Time
| '''5'''
+
| second (s)
| Number of radial cells.
 
 
|-
 
|-
| 1*integer
+
| 4
| N<sub>phi</sub>
+
| Temperature
| '''1'''
+
| Kelvin (K)
| Number of angular cells.
 
 
|-
 
|-
|
+
| 5
| ''Information on mesh boundaries''
+
| Quantity
|
+
| mole (mol)  
|
 
|-
 
| (N<sub>r</sub> + 1)*float
 
| r<sub>0</sub>, r<sub>1</sub>, r<sub>2</sub>, ...
 
| '''0.0''', '''0.1e-2''', '''0.2e-2''', '''0.3e-2''', '''0.4e-2'''
 
| The cell boundaries for the mesh in the radial direction.
 
|-
 
| (N<sub>phi</sub> + 1)*float
 
| phi<sub>0</sub>, phi<sub>1</sub>, phi<sub>2</sub>, ...
 
| '''0''', '''360'''
 
| The cell boundaries for the mesh in the angular direction (degrees, as in polar coordinates).
 
 
|}
 
|}
  
==== Default indexing ====
+
This means that some of the basic fields that we might transfer will have types of
 
 
Radial indexing runs fastest and angular indexing slower.
 
 
 
=== Type 8 &mdash; Nested mesh ===
 
  
 
{|class="wikitable" style="text-align: left;"
 
{|class="wikitable" style="text-align: left;"
! Data type/size
+
! Field name
! Data content (explanation)
+
! SI unit
! Data content (example)
+
! Basic unit
! Notes
+
! Unit array
 
|-
 
|-
| 1*integer
+
| Mass density
| Mesh type
+
| kg/m3
| '''8'''
+
| kg*m-3
|
+
| <tt>&#160;1 -3 &#160;0 &#160;0 &#160;0</tt>
 
|-
 
|-
| 1*integer
+
| Temperature
| N<sub>m</sub>
+
| K
| '''2'''
+
| K
| Number of nested meshes.
+
| <tt>&#160;0 &#160;0 &#160;0 &#160;1 &#160;0</tt>  
 
|-
 
|-
|  
+
| Power (integral)
| ''Information on'' N<sub>m</sub> ''nested meshes''
+
| W
|
+
| kg*m2*s-3
|
+
| <tt>&#160;1 &#160;2 -3 &#160;0 &#160;0</tt>  
 
|-
 
|-
|
+
| Power density
|
+
| W/m3
|
+
| kg*m-1*s-3
|
+
| <tt>&#160;1 -1 -3 &#160;0 &#160;0</tt>
|-
 
| 1*integer
 
| Mesh 1 type (top level)
 
| '''1'''
 
|
 
|-
 
|  
 
| ... ''The rest of the mesh 1 data.''
 
|
 
|
 
|-
 
|
 
|
 
|
 
|
 
|-
 
|
 
| Mesh 2 type (second highest level)
 
| '''1'''
 
|
 
|-
 
|
 
| ... ''The rest of the mesh 2 data.''
 
|
 
|
 
|-
 
|
 
|
 
|
 
|
 
|-
 
|
 
| Mesh  N<sub>m</sub> type (lowest level)
 
| '''1'''
 
|
 
|-
 
|
 
| ... ''The rest of the mesh'' N<sub>m</sub> ''data.''
 
|
 
|
 
|}
 
 
 
 
 
=== Type 9 &mdash; List ===
 
 
 
The list mesh type does not have any clearly defined spatial structure. It may be useful for passing in data, for which the exact geometric configuration is irrelevant.
 
 
 
{|class="wikitable" style="text-align: left;"
 
! Data type/size
 
! Data content (explanation)
 
! Data content (example)
 
! Notes
 
|-
 
| 1*integer
 
| Mesh type
 
| '''9'''
 
|
 
|-
 
| 1*integer
 
| N<sub>val</sub>
 
| '''10'''
 
| Number of values in the list.
 
 
|}
 
|}
 
== Indexing array ==
 
 
Each of the mesh types described in the previous section have their own ''default indexing'' sometimes referred to as ''global indexing''.
 
 
Sometimes the data accepted or provided by a solver may lie on a specific mesh type but follow an indexing that is different from this default. Consider the situation in the following figure:
 
 
[[File:2x2remap.png|frameless|200px|2x2 rod indexing information.]]
 
 
The red numbers indicate the default indexing in this 2x2x1 regular Cartesian mesh. If our coupled solver would have the inverse indexing shown in white, we would have to account for that fact in the data transfer. The idea in the Cerberus coupling is to allow the coupled solvers to send and receive data in their preferred indexing, so that the coupled solvers do not have to rearrange data when sending or receiving it. This is achieved by the option to provide an indexing array as a part of a field template.
 
 
The indexing array, which needs to be sent if the indexing flag in the sent field template is set to '''1''' is simply an array of integers with the length of the array corresponding to the number of cells in the mesh and the contents of the array describing which solver index (white) corresponds to which global index (red). The first value of the array indicates the solver index corresponding to global index '''1''' and so on.
 
 
The indexing array for our 2x2 example above would thus be
 
 
'''4 3 2 1'''
 
 
The indexing array can also account for the fact that the coupled solver will not accept or provide data for specific cell index/indices. If the coupled solver would only provide data for fuel rods and the geometry for the simulation would be as follows:
 
 
[[File:3x3remap.png|frameless|300px|3x3 rod indexing information with one non-indexed position.]]
 
 
In this case the coupled solver does not consider the global cell '''5''' to be a part of its solution domain and thus will not provide or accept field data for that cell. Global cell '''5''' can be left un-indexed by setting the value '''0''' for it in the indexing array, which would now be
 
 
'''8 7 6 5 0 4 3 2 1'''
 
 
In such cases where some mesh cells are not indexed, the number of values for the field transferred between Cerberus and the solver will be reduced. In this case only 8 values would be transferred in the [[#giveFieldData|giveFieldData]] and [[#takeFieldData|takeFieldData]] calls.
 
 
Extending the previous example from 3x3x1 to 3x3x2 the indexing array might be
 
 
'''8 7 6 5 0 4 3 2 1 16 15 14 13 0 12 11 10 9'''
 
 
assuming that the indexing of the coupled solver on the upper axial layer is similar to that in the lower axial layer shown in the previous figure.
 

Latest revision as of 12:28, 3 February 2024

The code coupling in Kraken is based on a "hub and spoke" approach where each solver module only needs to communicate with the central multi-physics driver Cerberus. The Cerberus multi-physics driver is responsible for starting up each solver module, exchanging field data with them and controlling the execution order of the different modules.

The individual solver modules should implement basic signalling capabilities so that they can accept signals from Cerberus as well as send messages back using the signalling syntax described below.

Basics of signalling

When the solver is executed from command line by Cerberus when running a Python script such as

# --- Initialize solvers
my_input = CodeInput("path_to_my_input")
my_solver = Solver("my_solver_name", path_to_my_solver, ["--port",])
my_solver.input = my_input
my_solver.initialize()

Cerberus will provide the port the solver should connect to as a pair of command line arguments "--port" <port_as_integer>. The solver should then read its own input, do whatever processing is required and open a socket on the indicated port for communication with Cerberus.

After the port has been opened, Cerberus expects the following greeting process:

Direction Name Size and type Content
Solver->Cerberus Lgreet 1*integer Length of greeting string in char excluding terminating character
Solver->Cerberus Lgreet*char A freely chosen greeting string (will be read and can be printed out by Cerberus).
Cerberus->Solver Lgreet 1*integer Length of greeting string in char excluding terminating character
Cerberus->Solver Lgreet*char Some greeting string sent by Cerberus.

After the greeting and its own basic initialization, the solver should wait for further signals from Cerberus.

After each order received from Cerberus, the solver should fulfill the order and wait for further signals from Cerberus.

All numerical values will be passed as double precision integers (8 bytes) or double precision floats (8 bytes).

Basic "function calls"

When the solvers have completed their previous order and are waiting for the next signal from Cerberus, Cerberus will initiate the communication with a single integer indicating which "function call" should be processed.

The function calls and the integers representing them in the communication syntax are listed in a table below. When coupling a solver to Cerberus, they are typically listed in some centrally located header (or some such) files for C and Fortran. These can be also checked from cerberus.commons.KrakenSignals.

Function name Integer value
terminate 0
returnCurrentTime 1
setCurrentTime 2
suggestNextTime 3
advanceToTime 4
solveCurrentTime 5
giveInputFieldNames 6
giveOutputFieldNames 7
giveFieldTemplate 8
giveMeshData 9
giveIndexingArray 10
giveFieldData 11
takeFieldData 12
giveOutputVariableDefs 13
giveVariableData 14
giveInputVariableDefs 15
takeVariableData 16
writeRestart 17
readRestart 18
returnCurrentTimeInterval 19
setCurrentTimeInterval 20
suggestNextTimeInterval 21
advanceToTimeInterval 22
correctPreviousStep 23

The following sections will go through the signalling for each of the function calls

terminate

When Cerberus sends the signal for a solver to terminate. The solver simply exits gracefully. Final results can be collected, processed and printed out. Memory should be freed, and the process should be terminated in the end.

No further signalling takes place after the C->S signal to terminate.

giveInputFieldNames

The solver should communicate the names of the fields it is expecting to receive from Cerberus. The communication syntax is as follows:

Direction Name Size and type Content
S->C NF 1*integer Number of fields to be provided
The following repeats NF times:
S->C Lname 1*integer Length of field name in char excluding terminating character
S->C Lname*char Name of the field

giveOutputFieldNames

The solver should communicate the names of the fields it is expecting to provide to Cerberus. The communication syntax is as follows:

Direction Name Size and type Content
S->C NF 1*integer Number of fields to be provided
The following repeats NF times:
S->C Lname 1*integer Length of field name in char excluding terminating character
S->C Lname*char Name of the field

giveFieldTemplate

The solver should provide basic information on the field requested by Cerberus.

The communication syntax is as follows:

Direction Name Size and type Content
C->S LnameF 1*integer Length of name of requested field (in char excluding terminating character).
C->S LnameF*char Name of the requested field
S->C 1*integer Data type (FLOAT = 1, INT = 2, STRING = 3)
S->C 5*integer Unit of the field in an OpenFOAMish array (see Field unit array)
S->C 1*float Multiplier a used to convert from the base unit type specified by the unit array to the actual unit used by the solver (a*x + b).
S->C 1*float Offset b used to convert from the base unit type specified by the unit array to the actual unit used by the solver (a*x + b).
S->C LnameM 1*integer Length of mesh name in char excluding terminating character
S->C LnameM*char Name of the mesh
S->C 1*integer Indexing flag: 0 if solver uses the default indexing of the mesh. 1 if solver uses some other indexing: Indexing array
[S->C] LnameI 1*integer Only if indexing flag was given as 1 (use custom indexing). Length of indexing array name in char excluding terminating character.
[S->C] LnameI*char Only if indexing flag was given as 1 (use custom indexing). Name of the indexing array.

giveMeshData

The solver should provide information on the mesh requested by Cerberus.

The communication syntax is as follows:

Direction Name Size and type Content
C->S Lname 1*integer Length of name of requested mesh (in char excluding terminating character).
C->S Lname*char Name of the requested mesh
S->C 1*integer Type of the mesh (see Mesh types).
S->C <depends on mesh> Mesh data, see subsection Mesh types

giveIndexingArray

The solver should provide information on the indexing array requested by Cerberus.

The communication syntax is as follows:

Direction Name Size and type Content
C->S Lname 1*integer Length of name of requested indexing array (in char excluding terminating character).
C->S Lname*char Name of the requested indexing array
S->C NV 1*integer Number of values to be passed.
S->C NV*value Indices: Indexing array

giveFieldData

The solver should provide the data for the field requested by Cerberus.

The communication syntax is as follows:

Direction Name Size and type Content
C->S Lname 1*integer Length of name of field to be passed (in char excluding terminating character).
C->S Lname*char Name of the field to be passed
S->C NV 1*integer Number of values to be passed.
S->C NV*value The values for the field (float, integer or strings).

takeFieldData

The solver should receive the data for the field indicated by Cerberus.

The communication syntax is as follows:

Direction Name Size and type Content
C->S Lname 1*integer Length of name of field to be passed (in char excluding terminating character).
C->S Lname*char Name of the field to be passed
C->S NV 1*integer Number of values to be passed.
C->S NV*value The values for the field (float, integer or strings).

giveOutputVariableDefs

The solver should communicate names of the variables it is expecting to provide to Cerberus. The communication syntax is as follows:

Direction Name Size and type Content
S->C NV 1*integer Number of variable definitions to be provided
The following repeats NV times:
S->C Lname 1*integer Length of name of variable to be passed (in char excluding terminating character).
S->C Lname*char Name of the variable to be passed
S->C 1*integer Data type (FLOAT = 1, INT = 2, STRING = 3)
S->C 1*integer Number of values to be passed.

giveVariableData

The solver should provide the variable requested by Cerberus.

The communication syntax is as follows:

Direction Name Size and type Content
C->S Lname 1*integer Length of name of variable to be passed (in char excluding terminating character).
C->S Lname*char Name of the variable to be passed
S->C NV 1*integer Number of values to be passed.
S->C NV*value Variable values (float, integer or strings).
S->C NV*float Only if statistics flag was given as 1. Relative errors.

giveInputVariableDefs

The solver should communicate names of the variables it is expecting to accept from Cerberus. The communication syntax is as follows:

Direction Name Size and type Content
S->C NV 1*integer Number of variable definitions to be provided
The following repeats NV times:
S->C Lname 1*integer Length of the name of the variable to be passed (in char excluding terminating character).
S->C Lname*char Name of the variable to be passed
S->C 1*integer Data type (FLOAT = 1, INT = 2, STRING = 3)
S->C 1*integer Number of values to be passed.

takeVariableData

The solver should receive the data for the variable indicated by Cerberus.

The communication syntax is as follows:

Direction Name Size and type Content
C->S Lname 1*integer Length of the name of the variable to be passed (in char excluding terminating character).
C->S Lname*char Name of the variable to be passed
C->S NV 1*integer Number of values to be passed.
C->S NV*value Variable values (float, integer or strings).

returnCurrentTime

The solver should return the time corresponding to the current time point as a float in seconds. This can be used to check that all solvers proceed at the same time points in burnup calculations.

Direction Name Size and type Content
S->C t1 1*float Current time point of the solver (seconds).

setCurrentTime

This method is usually called in the beginning of burnup calculations to set the starting time of the simulation. The solver should store the received time (a float in seconds) as the current time point and conduct any additional processing required.

Direction Name Size and type Content
C->S t1 1*float Time point to be set (seconds).

suggestNextTime

The solver should return a preferred length for the next time point (end of next timestep) as a float in seconds.

Direction Name Size and type Content
S->C t1 1*float Suggested next time point (seconds).

advanceToTime

The solver should advance to the next time point (time step), with the given value in seconds. This process may involve storing final results for the previous time point (time step), time integration of some data forwards to the next time point (e.g. burnup accumulation) etc.

Direction Name Size and type Content
C->S t1 1*float Next time point (seconds).

returnCurrentTimeInterval

The solver should provide information on the time interval it is currently solving to Cerberus (used in transient calculations):

Direction Name Size and type Content
S->C t0 1*float Beginning time of current interval (seconds).
S->C t1 1*float End time of current interval (seconds).

setCurrentTimeInterval

Cerberus provides the solver information on the time interval to be solved and the solver should adjust itself accordingly (used in transient calculations):

Direction Name Size and type Content
C->S t0 1*float Beginning time of current interval (seconds).
C->S t1 1*float End time of current interval (seconds).

suggestNextTimeInterval

The solver should provide its suggestion for the next time interval to be solved (used in transient calculations):

Direction Name Size and type Content
S->C t0 1*float Suggested beginning time of next time interval (seconds).
S->C t1 1*float Suggested end time of next time interval (seconds).

The beginning time of the next time interval should be equal to the end time of the current time interval.

advanceToTimeInterval

Cerberus provides the solver information on the next time interval to be solved. The solver should prepare itself for solving the new time interval next (e.g. by setting the end-of-interval data of the previous time-interval to be used as beginning-of-interval data for the upcoming one). Used in transient calculations.

Direction Name Size and type Content
C->S t0 1*float Beginning time of the next time interval (seconds).
C->S t1 1*float End time of the next time interval (seconds).

The beginning time of the next interval is more or less guaranteed to be the end time of the current interval.

solveCurrentTime

The solver should execute the solution for the current time point (time step). This can include some initialization and post-processing for the current solution if needed.

After the solution has completed, the solver should send Cerberus an integer value indicating that the solution has been completed and to give some information on the potential convergence of the solution (as judged by the solver):

Direction Name Size and type Content
S->C NV 1*integer A single integer 1, 2 or 3 (see below)
1 = solution complete
2 = solution complete and convergence reached
3 = solution complete but diverged or other problems

correctPreviousStep

The solver may consider the current coupled solution converged and use this information to correct the previous time-integral that took the solver to the current time/time interval. If the solver cannot correct its previous time-integration or does not deem it necessary, it can simply ignore the signal.

Intended especially for burnup calculations but might be useful in some transient simulations also.

writeRestart

The solver should write its current state as a restart file. The path to the restart file may be fixed, given as a part of the solver input or as an input variable through Cerberus.

The contents of the restart file can be freely chosen by the developer and may be context dependent, e.g. on the simulation type that is being executed (stationary, burnup, transient etc.)

readRestart

The solver should set its internal state based on a restart file. The path to the restart file may be fixed, given as a part of the solver input or as an input variable through Cerberus.

Along with the writeRestart method, this one should allow e.g. for initializing a transient simulation based on a stationary state or continuing a previous calculation in another manner. The exact functionality can be chosen by the developer.

Field unit array

The field unit array consists of 5 integers (e.g.  1 -3  0  0  0 for mass density) specifying the dimension for each of the 5 SI base units for the field

No. Property Unit
1 Mass kilogram (kg)
2 Length metre (m)
3 Time second (s)
4 Temperature Kelvin (K)
5 Quantity mole (mol)

This means that some of the basic fields that we might transfer will have types of

Field name SI unit Basic unit Unit array
Mass density kg/m3 kg*m-3  1 -3  0  0  0
Temperature K K  0  0  0  1  0
Power (integral) W kg*m2*s-3  1  2 -3  0  0
Power density W/m3 kg*m-1*s-3  1 -1 -3  0  0