Difference between revisions of "Code coupling in Kraken"
(→giveVariableData) |
(→Basic "function calls") |
||
(98 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 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 == | == Basics of signalling == | ||
− | When the solver is executed from command line by Cerberus | + | 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. | ||
− | All numerical values will be passed as double precision integers or double precision floats. | + | 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. | ||
+ | |||
+ | All numerical values will be passed as double precision integers (8 bytes) or double precision floats (8 bytes). | ||
== Basic "function calls" == | == Basic "function calls" == | ||
Line 15: | 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 | + | 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]. |
− | + | {|class="wikitable" style="text-align: left;" | |
− | + | !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 | The following sections will go through the signalling for each of the function calls | ||
Line 42: | 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. | ||
− | === | + | === giveInputFieldNames === |
+ | |||
+ | 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;" | ||
+ | !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 | ||
+ | |} | ||
+ | |||
+ | === giveOutputFieldNames === | ||
− | The solver should communicate | + | 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;" | {|class="wikitable" style="text-align: left;" | ||
Line 54: | Line 186: | ||
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}} | | {{highlight|S|tomato}}->{{highlight|C|PaleGreen}} | ||
| NF | | NF | ||
− | | | + | | 1*integer |
| Number of fields to be provided | | Number of fields to be provided | ||
|- | |- | ||
Line 70: | Line 202: | ||
| | | | ||
| Lname*char | | Lname*char | ||
− | | Name of the field | + | | 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 80: | 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 | ||
− | | | + | | Length of mesh name in char excluding terminating character |
|- | |- | ||
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}} | | {{highlight|S|tomato}}->{{highlight|C|PaleGreen}} | ||
| | | | ||
− | | | + | | LnameM*char |
− | | | + | | 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}}] | ||
| | | | ||
− | | | + | | LnameI*char |
− | | Only if indexing flag was given as '''1''' (use custom indexing) | + | | 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: | |
{|class="wikitable" style="text-align: left;" | {|class="wikitable" style="text-align: left;" | ||
Line 115: | Line 285: | ||
!Content | !Content | ||
|- | |- | ||
− | | | + | | {{highlight|C|PaleGreen}}->{{highlight|S|tomato}} |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
| Lname | | Lname | ||
| 1*integer | | 1*integer | ||
− | | Length of | + | | Length of name of requested mesh (in char excluding terminating character). |
|- | |- | ||
− | | {{highlight| | + | | {{highlight|C|PaleGreen}}->{{highlight|S|tomato}} |
| | | | ||
| Lname*char | | Lname*char | ||
− | | Name of the | + | | Name of the requested mesh |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
|- | |- | ||
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}} | | {{highlight|S|tomato}}->{{highlight|C|PaleGreen}} | ||
| | | | ||
| 1*integer | | 1*integer | ||
− | | Type of the mesh | + | | Type of the mesh (see [[Mesh types]]). |
|- | |- | ||
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}} | | {{highlight|S|tomato}}->{{highlight|C|PaleGreen}} | ||
Line 154: | 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|S|tomato}}- | + | | {{highlight|C|PaleGreen}}->{{highlight|S|tomato}} |
+ | | Lname | ||
+ | | 1*integer | ||
+ | | Length of name of requested indexing array (in char excluding terminating character). | ||
+ | |- | ||
+ | | {{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 | ||
− | | | + | | Number of values to be passed. |
|- | |- | ||
− | | | + | | {{highlight|S|tomato}}->{{highlight|C|PaleGreen}} |
| | | | ||
− | | | + | | NV*value |
− | | | + | | Indices: [[Mesh types#Indexing array|Indexing array]] |
|} | |} | ||
− | |||
− | |||
=== giveFieldData === | === giveFieldData === | ||
Line 197: | Line 368: | ||
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}} | | {{highlight|S|tomato}}->{{highlight|C|PaleGreen}} | ||
| | | | ||
− | | NV* | + | | NV*value |
− | | The values for the field. | + | | The values for the field (float, integer or strings). |
|} | |} | ||
− | |||
− | |||
=== takeFieldData === | === takeFieldData === | ||
Line 232: | Line 401: | ||
| {{highlight|C|PaleGreen}}->{{highlight|S|tomato}} | | {{highlight|C|PaleGreen}}->{{highlight|S|tomato}} | ||
| | | | ||
− | | NV* | + | | NV*value |
− | | The values for the field. | + | | 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: | The solver should communicate names of the variables it is expecting to provide to Cerberus. The communication syntax is as follows: | ||
Line 251: | Line 418: | ||
| NV | | NV | ||
| 1*integer | | 1*integer | ||
− | | Number of | + | | Number of variable definitions to be provided |
|- | |- | ||
| The following repeats NV times: | | The following repeats NV times: | ||
Line 258: | Line 425: | ||
| | | | ||
|- | |- | ||
− | | {{highlight|S|tomato}}->{{highlight|C|PaleGreen}} | + | | {{highlight|S|tomato}}->{{highlight|C|PaleGreen}} |
| Lname | | Lname | ||
| 1*integer | | 1*integer | ||
− | | Length of | + | | Length of name of variable to be passed (in char excluding terminating character). |
+ | |- | ||
+ | | {{highlight|S|tomato}}->{{highlight|C|PaleGreen}} | ||
+ | | | ||
+ | | Lname*char | ||
+ | | Name of the variable to be passed | ||
|- | |- | ||
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}} | | {{highlight|S|tomato}}->{{highlight|C|PaleGreen}} | ||
| | | | ||
− | | | + | | 1*integer |
− | | | + | | Data type (FLOAT = '''1''', INT = '''2''', STRING = '''3''') |
+ | |- | ||
+ | | {{highlight|S|tomato}}->{{highlight|C|PaleGreen}} | ||
+ | | | ||
+ | | 1*integer | ||
+ | | Number of values to be passed. | ||
|} | |} | ||
− | |||
− | |||
=== giveVariableData === | === giveVariableData === | ||
Line 292: | 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}} | | {{highlight|S|tomato}}->{{highlight|C|PaleGreen}} | ||
Line 305: | Line 475: | ||
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}} | | {{highlight|S|tomato}}->{{highlight|C|PaleGreen}} | ||
| | | | ||
− | | NV* | + | | NV*value |
− | | Variable values. | + | | Variable values (float, integer or strings). |
|- | |- | ||
| {{highlight|S|tomato}}->{{highlight|C|PaleGreen}} | | {{highlight|S|tomato}}->{{highlight|C|PaleGreen}} | ||
Line 314: | Line 484: | ||
|} | |} | ||
− | + | === giveInputVariableDefs === | |
− | |||
− | === | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | The solver should communicate names of the variables it is expecting to accept from Cerberus. The communication syntax is as follows: | |
− | |||
− | |||
− | |||
− | The solver should | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | The | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
{|class="wikitable" style="text-align: left;" | {|class="wikitable" style="text-align: left;" | ||
− | ! | + | !Direction |
− | ! | + | !Name |
− | ! | + | !Size and type |
+ | !Content | ||
|- | |- | ||
− | | | + | | {{highlight|S|tomato}}->{{highlight|C|PaleGreen}} |
− | | | + | | NV |
− | | | + | | 1*integer |
+ | | Number of variable definitions to be provided | ||
|- | |- | ||
− | | | + | | The following repeats NV times: |
− | | | + | | |
− | | | + | | |
+ | | | ||
|- | |- | ||
− | | | + | | {{highlight|S|tomato}}->{{highlight|C|PaleGreen}} |
− | | | + | | Lname |
− | | | + | | 1*integer |
+ | | Length of the name of the variable to be passed (in char excluding terminating character). | ||
|- | |- | ||
− | | | + | | {{highlight|S|tomato}}->{{highlight|C|PaleGreen}} |
− | | | + | | |
− | | | + | | Lname*char |
+ | | Name of the variable to be passed | ||
|- | |- | ||
− | | | + | | {{highlight|S|tomato}}->{{highlight|C|PaleGreen}} |
− | | | + | | |
− | | | + | | 1*integer |
− | |} | + | | Data type (FLOAT = '''1''', INT = '''2''', STRING = '''3''') |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
|- | |- | ||
− | | | + | | {{highlight|S|tomato}}->{{highlight|C|PaleGreen}} |
− | + | | | |
− | + | | 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: | |
− | |||
− | |||
{|class="wikitable" style="text-align: left;" | {|class="wikitable" style="text-align: left;" | ||
− | ! | + | !Direction |
− | ! | + | !Name |
− | ! | + | !Size and type |
− | ! | + | !Content |
|- | |- | ||
− | | | + | | {{highlight|C|PaleGreen}}->{{highlight|S|tomato}} |
− | | | + | | Lname |
− | | | + | | 1*integer |
− | | | + | | Length of the name of the variable to be passed (in char excluding terminating character). |
|- | |- | ||
+ | | {{highlight|C|PaleGreen}}->{{highlight|S|tomato}} | ||
| | | | ||
− | | | + | | Lname*char |
− | + | | Name of the variable to be passed | |
− | | | ||
|- | |- | ||
− | | | + | | {{highlight|C|PaleGreen}}->{{highlight|S|tomato}} |
− | | | + | | NV |
− | | | + | | 1*integer |
− | | | + | | Number of values to be passed. |
|- | |- | ||
− | | | + | | {{highlight|C|PaleGreen}}->{{highlight|S|tomato}} |
− | | | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |- | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | | | ||
− | | | ||
| | | | ||
− | | | + | | 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. | |
− | + | {|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). | ||
+ | |} | ||
− | + | === setCurrentTime === | |
− | The | + | 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. |
{|class="wikitable" style="text-align: left;" | {|class="wikitable" style="text-align: left;" | ||
− | ! | + | !Direction |
− | ! | + | !Name |
− | ! | + | !Size and type |
− | ! | + | !Content |
|- | |- | ||
− | | | + | | {{highlight|C|PaleGreen}}->{{highlight|S|tomato}} |
− | + | | 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. | |
− | + | {|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 === |
− | + | 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. | |
− | + | {|class="wikitable" style="text-align: left;" | |
+ | !Direction | ||
+ | !Name | ||
+ | !Size and type | ||
+ | !Content | ||
+ | |- | ||
+ | | {{highlight|C|PaleGreen}}->{{highlight|S|tomato}} | ||
+ | | 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'''): | |
− | + | {|class="wikitable" style="text-align: left;" | |
+ | !Direction | ||
+ | !Name | ||
+ | !Size and type | ||
+ | !Content | ||
+ | |- | ||
+ | | {{highlight|S|tomato}}->{{highlight|C|PaleGreen}} | ||
+ | | t0 | ||
+ | | 1*float | ||
+ | | Beginning time of current interval (seconds). | ||
+ | |- | ||
+ | | {{highlight|S|tomato}}->{{highlight|C|PaleGreen}} | ||
+ | | 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'''): | |
− | + | {|class="wikitable" style="text-align: left;" | |
+ | !Direction | ||
+ | !Name | ||
+ | !Size and type | ||
+ | !Content | ||
+ | |- | ||
+ | | {{highlight|C|PaleGreen}}->{{highlight|S|tomato}} | ||
+ | | t0 | ||
+ | | 1*float | ||
+ | | Beginning time of current interval (seconds). | ||
+ | |- | ||
+ | | {{highlight|C|PaleGreen}}->{{highlight|S|tomato}} | ||
+ | | 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'''): | |
− | + | {|class="wikitable" style="text-align: left;" | |
+ | !Direction | ||
+ | !Name | ||
+ | !Size and type | ||
+ | !Content | ||
+ | |- | ||
+ | | {{highlight|S|tomato}}->{{highlight|C|PaleGreen}} | ||
+ | | t0 | ||
+ | | 1*float | ||
+ | | Suggested beginning time of next time interval (seconds). | ||
+ | |- | ||
+ | | {{highlight|S|tomato}}->{{highlight|C|PaleGreen}} | ||
+ | | 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'''. | |
{|class="wikitable" style="text-align: left;" | {|class="wikitable" style="text-align: left;" | ||
− | ! | + | !Direction |
− | ! | + | !Name |
− | ! | + | !Size and type |
− | ! | + | !Content |
|- | |- | ||
− | | | + | | {{highlight|C|PaleGreen}}->{{highlight|S|tomato}} |
− | | | + | | t0 |
− | | | + | | 1*float |
− | | | + | | Beginning time of the next time interval (seconds). |
|- | |- | ||
− | | 1* | + | | {{highlight|C|PaleGreen}}->{{highlight|S|tomato}} |
− | | | + | | 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): | ||
+ | {|class="wikitable" style="text-align: left;" | ||
+ | !Direction | ||
+ | !Name | ||
+ | !Size and type | ||
+ | !Content | ||
|- | |- | ||
− | | | + | | {{highlight|S|tomato}}->{{highlight|C|PaleGreen}} |
− | + | | NV | |
− | | | + | | 1*integer |
− | + | | A single integer 1, 2 or 3 (see below) | |
− | |- | ||
− | |||
− | |||
− | | | ||
− | | | ||
− | | | ||
− | | 1*integer | ||
− | | | ||
− | |||
− | |||
|- | |- | ||
| | | | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
| | | | ||
− | |||
− | |||
| | | | ||
+ | | 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|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 | + | The field unit array consists of 5 integers (e.g. <tt> 1 -3  0  0  0</tt> for mass density) specifying the dimension for each of the 5 SI base units for the field |
− | + | {|class="wikitable" style="text-align: left;" | |
+ | ! 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 | |
− | + | {|class="wikitable" style="text-align: left;" | |
− | + | ! Field name | |
− | + | ! SI unit | |
− | + | ! Basic unit | |
− | + | ! Unit array | |
− | + | |- | |
− | + | | Mass density | |
− | + | | kg/m3 | |
− | + | | kg*m-3 | |
− | + | | <tt> 1 -3  0  0  0</tt> | |
− | + | |- | |
− | + | | Temperature | |
− | + | | K | |
+ | | K | ||
+ | | <tt> 0  0  0  1  0</tt> | ||
+ | |- | ||
+ | | Power (integral) | ||
+ | | W | ||
+ | | kg*m2*s-3 | ||
+ | | <tt> 1  2 -3  0  0</tt> | ||
+ | |- | ||
+ | | Power density | ||
+ | | W/m3 | ||
+ | | kg*m-1*s-3 | ||
+ | | <tt> 1 -1 -3  0  0</tt> | ||
+ | |} |
Latest revision as of 11: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.
Contents
- 1 Basics of signalling
- 2 Basic "function calls"
- 2.1 terminate
- 2.2 giveInputFieldNames
- 2.3 giveOutputFieldNames
- 2.4 giveFieldTemplate
- 2.5 giveMeshData
- 2.6 giveIndexingArray
- 2.7 giveFieldData
- 2.8 takeFieldData
- 2.9 giveOutputVariableDefs
- 2.10 giveVariableData
- 2.11 giveInputVariableDefs
- 2.12 takeVariableData
- 2.13 returnCurrentTime
- 2.14 setCurrentTime
- 2.15 suggestNextTime
- 2.16 advanceToTime
- 2.17 returnCurrentTimeInterval
- 2.18 setCurrentTimeInterval
- 2.19 suggestNextTimeInterval
- 2.20 advanceToTimeInterval
- 2.21 solveCurrentTime
- 2.22 correctPreviousStep
- 2.23 writeRestart
- 2.24 readRestart
- 3 Field unit array
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 |