From 530c2e1ee95c1b1f75ca39998c2c23c894a2a412 Mon Sep 17 00:00:00 2001 From: Philip Top Date: Thu, 26 Sep 2024 05:59:40 -0700 Subject: [PATCH 1/8] add some test scripts from matHELICS --- .github/workflows/ci.yml | 49 +++++++++++++++++++++++++++ .github/workflows/update-helics.yml | 51 +++++++++++++++++++++++++++++ README.md | 6 +++- 3 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/update-helics.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..fbdd318 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,49 @@ +name: Test matHELICS + +on: + push: + pull_request: + branches: + - main + workflow_dispatch: + #schedule: + # - cron: "35 10 * * 1,3,5 # running early in the morning (UTC) + +jobs: + ci-test: + strategy: + fail-fast: false + matrix: + os: [windows-2019,macos-11,ubuntu-20.04] + runs-on: ${{ matrix.os }} + steps: + - name: Check out repository + uses: actions/checkout@v3 + - name: Install latest HELICS release + uses: gmlc-tdc/helics-action/install@main + - name: Set up MATLAB + uses: matlab-actions/setup-matlab@v1.1.1 + with: + release: R2021a + - name: Set up MEX + uses: matlab-actions/run-command@v1 + with: + command: mex -setup + - name: Build matHELICS + uses: matlab-actions/run-command@v1 + with: + command: buildHelicsInterface('helics',true) + - name: store package + uses: actions/upload-artifact@v3 + with: + name: ${{ matrix.os }}-matHELICS + path: matHELICS.* + - name: run startup + uses: matlab-actions/run-command@v1 + with: + command: addpath('helics'), helicsStartup + - name: run tests + uses: matlab-actions/run-command@v1 + with: + command: addpath('tests'),addpath('helics'),runAllTests + diff --git a/.github/workflows/update-helics.yml b/.github/workflows/update-helics.yml new file mode 100644 index 0000000..d094e22 --- /dev/null +++ b/.github/workflows/update-helics.yml @@ -0,0 +1,51 @@ +name: Update HELICS Version + +on: + workflow_dispatch: + inputs: + version: + description: 'HELICS version number' + required: true + type: string + dryrun: + description: 'Do a dry run of the update process, without making the commit' + required: false + type: boolean + + +jobs: + update-helics-version: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Set git config for commits + run: | + git config --global user.name "github-actions[bot]" + git config --global user.email "github-actions[bot]@users.noreply.github.com" + + - name: Update HELICS version number + run: | + # Update lines in the package file + version_line="HelicsVersion='${{ inputs.version }}';" + echo "::group::buildHelicsInterface.m version line" + echo "$version_line" + echo "::endgroup::" + sed -i "/HelicsVersion=/c ${version_line}" buildHelicsInterface.m + + git add buildHelicsInterface.m + + echo "::group::git diff --staged" + git diff --staged + echo "::endgroup::" + + git commit -m "Bump HELICS download version to ${{ inputs.version }}" + + echo "::group::git show" + git show + echo "::endgroup::" + + if [ "${{ inputs.dryrun }}" = "false" ]; then + echo "Pushing changes" + git push + fi diff --git a/README.md b/README.md index b60c420..cd72c5c 100644 --- a/README.md +++ b/README.md @@ -89,4 +89,8 @@ T. Hardy, B. Palmintier, P. Top, D. Krishnamurthy and J. Fuller, "HELICS: A Co-S ## Release HELICS, simHELICS and many associated repositories are distributed under the terms of the BSD-3 clause license. All new -contributions must be made under this license. [LICENSE](LICENSE) \ No newline at end of file +contributions must be made under this license. [LICENSE](LICENSE) + +SPDC-License-Identifier: BSD-3-Clause + +Portions of the code written by LLNL with release number LLNL-CODE-866414 From 44bc2152d5366fe47d086baa9d2eb364dff38e4e Mon Sep 17 00:00:00 2001 From: Philip Top Date: Thu, 26 Sep 2024 06:15:11 -0700 Subject: [PATCH 2/8] update pre-commit file --- .pre-commit-config.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 40b40d3..d8faa82 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,7 +1,7 @@ exclude: ^(ThirdParty/|test/files/|.github/workflows/|.github/actions/) repos: - repo: https://github.com/jumanjihouse/pre-commit-hooks - rev: 2.1.6 + rev: 3.0.0 hooks: - id: markdownlint args: [-s, ./config/.markdownlintrc] @@ -15,16 +15,16 @@ repos: hooks: - id: prettier - repo: https://github.com/Lucas-C/pre-commit-hooks - rev: v1.1.13 + rev: v1.5.5 hooks: - id: remove-tabs - repo: https://github.com/codespell-project/codespell - rev: v2.1.0 + rev: v2.3.0 hooks: - id: codespell exclude: ^(test/) - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.1.0 + rev: v4.6.0 hooks: - id: mixed-line-ending - id: trailing-whitespace @@ -35,7 +35,7 @@ repos: - id: end-of-file-fixer - id: check-shebang-scripts-are-executable - repo: https://github.com/pre-commit/mirrors-clang-format - rev: v13.0.1 + rev: v19.1.0 hooks: - id: clang-format types: From bd4b1319b050b4144217648d5c741e8d875f2a41 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 26 Sep 2024 13:17:36 +0000 Subject: [PATCH 3/8] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .gitignore | 3 ++- README.md | 20 +++++++-------- buildSimHELICS.m | 11 +++----- example/cosim.json | 56 ++++++++++++++++++++--------------------- example/sim_config.json | 2 +- helics_federate.c | 12 ++++----- helics_input.c | 16 ++++++------ helics_minimal.h | 14 +++++------ helics_publication.c | 12 ++++----- 9 files changed, 72 insertions(+), 74 deletions(-) diff --git a/.gitignore b/.gitignore index a3d97f5..6ea0eaf 100644 --- a/.gitignore +++ b/.gitignore @@ -316,7 +316,8 @@ venv* .LSOverride # Icon must end with two \r -Icon +Icon + # Thumbnails ._* diff --git a/README.md b/README.md index cd72c5c..eb4b7e7 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,9 @@ For HELICS documentation see [HELICS.org](www.helics.org) For other platforms the installation is as simple as downloading this repository and inside matlab executing the `buildSimHELICS` Matlab script. -This should download the required HELICS binary files and compile the platform specific mex file. This does require a compiler be installed on the system and executing inside matlab +This should download the required HELICS binary files and compile the platform specific mex file. This does require a compiler be installed on the system and executing inside matlab -``` matlab +```matlab >> mex -setup ``` @@ -20,14 +20,14 @@ This setup is only once on any given Matlab installation and does not need to be >> buildSimHELICS('../helics'); ``` -this will generate the helics interface in a folder 1 level above the simHELICS directory. If desired it can also be built in the simHELICS directory for example: +this will generate the helics interface in a folder 1 level above the simHELICS directory. If desired it can also be built in the simHELICS directory for example: ```matlabs >> cd simHELICS >> buildSimHELICS(); ``` -The `buildSimHELICS` function also has an option to generate the package file. This can be used to generate a package that can be transfered to a similar system. +The `buildSimHELICS` function also has an option to generate the package file. This can be used to generate a package that can be transfered to a similar system. This is a new process for building a simulink interface, it is tested but not extensively and not on a large variety of platforms if you run into issues please let us know. @@ -53,29 +53,29 @@ These simulink blocks are in a simHELICS.slx library object and can be loaded or ### federate block -The federate block takes 1 parameter which is the name of a config file. This config file is typically json, but other formats including a direct string input is allowed. This configuration json is the only means of configuring the federate in simulink. All interfaces should be specified in this configuraiton file. +The federate block takes 1 parameter which is the name of a config file. This config file is typically json, but other formats including a direct string input is allowed. This configuration json is the only means of configuring the federate in simulink. All interfaces should be specified in this configuraiton file. ### input block -The input block is used to retreive data from HELICS. It takes two parameters. The first is an integer or string with the input index(zero based) or name resepectively, and some arguments as a string as the second argument. Allowed arguments are 'output_size=X', and 'output_type=XXXX'. These define the size and type of the simulink output on the block. Default for an empty string is 1, and double. 'double','int', 'bool', and 'complex' are supported along with 'vector' and 'complex_vector'. The HELICS interface type is defined in the configuration. This is defining the desired output type in simulink. +The input block is used to retreive data from HELICS. It takes two parameters. The first is an integer or string with the input index(zero based) or name resepectively, and some arguments as a string as the second argument. Allowed arguments are 'output_size=X', and 'output_type=XXXX'. These define the size and type of the simulink output on the block. Default for an empty string is 1, and double. 'double','int', 'bool', and 'complex' are supported along with 'vector' and 'complex_vector'. The HELICS interface type is defined in the configuration. This is defining the desired output type in simulink. -The input_block is wired to the helics_federate block. +The input_block is wired to the helics_federate block. ### Publication block -The publication block is used to send data via HELICS. The first is an integer or string with the publication index(zero based) or name resepectively, and some arguments as a string as the second argument. Allowed arguments are 'input_size=X', and 'input_type=XXXX'. These define the size and type of the second simulink input on the block. Default for an empty string argument is 1, and double. 'double','int', 'bool', and 'complex' are supported along with 'vector' and 'complex_vector'. The HELICS interface type is defined in the configuration. This is defining the desired input type and size in simulink. +The publication block is used to send data via HELICS. The first is an integer or string with the publication index(zero based) or name resepectively, and some arguments as a string as the second argument. Allowed arguments are 'input_size=X', and 'input_type=XXXX'. These define the size and type of the second simulink input on the block. Default for an empty string argument is 1, and double. 'double','int', 'bool', and 'complex' are supported along with 'vector' and 'complex_vector'. The HELICS interface type is defined in the configuration. This is defining the desired input type and size in simulink. The publication is block is wired to the helics_federate block and the data wishing to be published. ### Example -A trivial example federate (test_fed.slx) is located in the example folder, along with a simple config file. This federate sends data to itself using a inproc federate and plots the result. +A trivial example federate (test_fed.slx) is located in the example folder, along with a simple config file. This federate sends data to itself using a inproc federate and plots the result. ## Building with older versions of Matlab If it is necessary to run on an older version of Matlab prior to 2018a, some minor modifications to the helicsMex.cpp may be possible to allow things to work fine, please contact the developers for specific instructions. -Versions prior to Matlab 2015 will require more extensive modifications. And may be better served by using the Swig based matlab build from Helics version 3.2 which should be compatible with other HELICS versions in the 3.X series. +Versions prior to Matlab 2015 will require more extensive modifications. And may be better served by using the Swig based matlab build from Helics version 3.2 which should be compatible with other HELICS versions in the 3.X series. ## Source Repo diff --git a/buildSimHELICS.m b/buildSimHELICS.m index 68e9448..54aadea 100644 --- a/buildSimHELICS.m +++ b/buildSimHELICS.m @@ -59,7 +59,7 @@ function buildSimHELICS(targetPath,makePackage) end %actually build the mex file fprintf('building helics mex target\n'); - + mex('-lhelics','-R2018a',['-I',basePath,'/include/'],['-L',basePath,'/lib'],['LDFLAGS=$LDFLAGS -Wl,-rpath,$ORIGIN/lib,-rpath,',basePath,'/lib',',-rpath,',basePath,'/lib64'],fullfile(inputPath,'helics_federate.c'),'-outdir',targetPath); mex('-lhelics','-R2018a',['-I',basePath,'/include/'],['-L',basePath,'/lib'],['LDFLAGS=$LDFLAGS -Wl,-rpath,$ORIGIN/lib,-rpath,',basePath,'/lib',',-rpath,',basePath,'/lib64'],fullfile(inputPath,'helics_input.c'),'-outdir',targetPath); mex('-lhelics','-R2018a',['-I',basePath,'/include/'],['-L',basePath,'/lib'],['LDFLAGS=$LDFLAGS -Wl,-rpath,$ORIGIN/lib,-rpath,',basePath,'/lib',',-rpath,',basePath,'/lib64'],fullfile(inputPath,'helics_publication.c'),'-outdir',targetPath); @@ -108,7 +108,7 @@ function buildSimHELICS(targetPath,makePackage) %copy the needed dll file if on windows if ispc if (~exist(fullfile(targetPath,targetFile),'file')) - + copyfile(fullfile(basePath,'bin',targetFile),fullfile(targetPath,targetFile)); copyfile(fullfile(basePath,'bin','*.dll'),targetPath); end @@ -118,7 +118,7 @@ function buildSimHELICS(targetPath,makePackage) end %% now build the interface directory and copy files fprintf('copying required files\n'); - + % copy the include directory with the C headers if (~exist(fullfile(targetPath,'include'),'dir')) mkdir(fullfile(targetPath,'include')); @@ -137,7 +137,7 @@ function buildSimHELICS(targetPath,makePackage) else copyfile(fullfile(basePath,'bin'),fullfile(targetPath,'bin')); end - + if (makePackage) fprintf('generating helics simulink binary package file\n'); rmdir(basePath,'s'); @@ -150,6 +150,3 @@ function buildSimHELICS(targetPath,makePackage) warning('unrecognized platform for making package'); end end - - - diff --git a/example/cosim.json b/example/cosim.json index bf2dab4..7513f5d 100644 --- a/example/cosim.json +++ b/example/cosim.json @@ -1,29 +1,29 @@ { - "name": "port_model", - "federates": [ - { - "directory": ".", - "exec": "helics_broker -f5", - "host": "localhost", - "name": "port_broker" - }, - { - "directory": ".", - "exec": "python -u port", - "host": "localhost", - "name": "port" - }, - { - "directory": ".", - "exec": "python -u visualization.py 1", - "host": "localhost", - "name": "vis" - }, - { - "directory": ".", - "exec": "python -u threat.py", - "host": "localhost", - "name": "threat" - } - ] - } \ No newline at end of file + "name": "port_model", + "federates": [ + { + "directory": ".", + "exec": "helics_broker -f5", + "host": "localhost", + "name": "port_broker" + }, + { + "directory": ".", + "exec": "python -u port", + "host": "localhost", + "name": "port" + }, + { + "directory": ".", + "exec": "python -u visualization.py 1", + "host": "localhost", + "name": "vis" + }, + { + "directory": ".", + "exec": "python -u threat.py", + "host": "localhost", + "name": "threat" + } + ] +} diff --git a/example/sim_config.json b/example/sim_config.json index 6608afc..8e51c72 100644 --- a/example/sim_config.json +++ b/example/sim_config.json @@ -1,7 +1,7 @@ { "name": "fedb", "coreType": "inproc", - "autobroker":true, + "autobroker": true, "period": 0.01, "uninterruptible": true, "wait_for_current_time_update": false, diff --git a/helics_federate.c b/helics_federate.c index 427281f..5e34547 100644 --- a/helics_federate.c +++ b/helics_federate.c @@ -27,11 +27,11 @@ static void mdlInitializeSizes(SimStruct *S) ssSetNumSampleTimes(S, 1); - + /* Set this S-function as runtime thread-safe for multicore execution */ ssSetRuntimeThreadSafetyCompliance(S, RUNTIME_THREAD_SAFETY_COMPLIANCE_TRUE); ssSetOptions(S,SS_OPTION_CALL_TERMINATE_ON_EXIT); - + ssSetNumDWork(S,2); ssSetDWorkDataType(S, 0, SS_DOUBLE); ssSetDWorkDataType(S, 1, SS_BOOLEAN); @@ -43,7 +43,7 @@ static void mdlInitializeSizes(SimStruct *S) static void mdlInitializeSampleTimes(SimStruct *S) { - + ssSetSampleTime(S, 0, VARIABLE_SAMPLE_TIME); } @@ -51,8 +51,8 @@ static void mdlInitializeSampleTimes(SimStruct *S) static void mdlGetTimeOfNextVarHit(SimStruct *S) { real_T *timing = (real_T*) ssGetDWork(S,0); - time_T timeOfNextHit = timing[0] + timing[2]; - ssSetTNext(S, timeOfNextHit); + time_T timeOfNextHit = timing[0] + timing[2]; + ssSetTNext(S, timeOfNextHit); } #define MDL_START @@ -133,4 +133,4 @@ static void mdlCleanupRuntimeResources(SimStruct *S) } } } -#include "simulink.c" /* MEX-file interface mechanism */ \ No newline at end of file +#include "simulink.c" /* MEX-file interface mechanism */ diff --git a/helics_input.c b/helics_input.c index 149a712..f8c9cd0 100644 --- a/helics_input.c +++ b/helics_input.c @@ -44,7 +44,7 @@ static void mdlInitializeSizes(SimStruct *S) { dataType=helicsGetDataType(token+12); ssPrintf("got token output_type read as %s converted to %d\n",token+12,dataType); - + } token=strtok(NULL," ,"); } @@ -65,7 +65,7 @@ static void mdlInitializeSizes(SimStruct *S) //something with complex indications break; } - + ssSetInputPortRequiredContiguous(S,0,1); /* sample times */ ssSetNumSampleTimes( S, 1 ); @@ -84,7 +84,7 @@ static void mdlInitializeSampleTimes(SimStruct *S) #define MDL_START void mdlStart(SimStruct *S) { - + } @@ -177,7 +177,7 @@ static void mdlOutputs(SimStruct *S, int_T tid) for (ii=sz;ii Date: Thu, 26 Sep 2024 06:33:58 -0700 Subject: [PATCH 4/8] update pre-commit --- .pre-commit-config.yaml | 18 +++++++++--------- config/.markdownlintrc | 27 +++++++++++++++++++++++++++ config/spelling_ignorelines.txt | 1 + config/spelling_whitelist.txt | 9 +++++++++ 4 files changed, 46 insertions(+), 9 deletions(-) create mode 100644 config/.markdownlintrc create mode 100644 config/spelling_ignorelines.txt create mode 100644 config/spelling_whitelist.txt diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d8faa82..6dc6548 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -11,7 +11,7 @@ repos: hooks: - id: cmake-format - repo: https://github.com/pre-commit/mirrors-prettier - rev: v2.6.1 + rev: v4.0.0-alpha.8 hooks: - id: prettier - repo: https://github.com/Lucas-C/pre-commit-hooks @@ -23,6 +23,13 @@ repos: hooks: - id: codespell exclude: ^(test/) + args: + [ + "-w", + "--skip=*.csv", + "--ignore-words=./config/spelling_whitelist.txt", + "--exclude-file=./config/spelling_ignorelines.txt", + ] - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.6.0 hooks: @@ -39,11 +46,4 @@ repos: hooks: - id: clang-format types: - - c++ - - repo: local - hooks: - - id: disallow-caps - name: Disallow improper capitalization - language: pygrep - entry: PyBind|Numpy|Cmake|CCache|PyTest|Github - exclude: .pre-commit-config.yaml + - c diff --git a/config/.markdownlintrc b/config/.markdownlintrc new file mode 100644 index 0000000..d1b9b6c --- /dev/null +++ b/config/.markdownlintrc @@ -0,0 +1,27 @@ +rule "MD001" # header levels increment by 1 +rule "MD003", :style => :atx # header style - atx +rule "MD004", :style => :dash # unordered list style - dash +#rule "MD005" # don't allow inconsistent indentation for list items managed by prettier +#rule "MD007", :indent => 2 # unordered list indentation should be 4 spaces managed by prettier +rule "MD009" # trailing spaces not allowed +rule "MD010" # hard tabs not allowed +rule "MD011" # alert on reversed link syntax +rule "MD012" # alert on multiple consecutive blank lines +#rule "MD013" # line length should be no more than 80 characters +#rule "MD014" # dollars signs not before commands w/o showing output +rule "MD018" # must have space after header style +rule "MD019" # no multiple spaces after header style +rule "MD022" # headers should be surrounded by blank lines +rule "MD023" # headers must start at the beginning of the line +rule "MD024", :allow_different_nesting => true # no multiple same level headers with same content +rule "MD025" # only 1 level 1 header +rule "MD026", :punctuation => '.,;:' # no trailing punctuation in headers +rule "MD027" # no multiple spaces after blockquote symbol +rule "MD028" # no blank lines within blockquote +#rule "MD029", :style => :ordered # ordered list item prefix, shoulded be ordered +#rule "MD030", :ul_single => 1, :ol_single => 1, :ul_multi => 1, :ol_multi => 3 # spaces after list markers, controlled by prettier +rule "MD031" # fenced code blocks need line surrounding +#rule "MD032" # lists should be surrounded by line # handled by prettier markdown formatting +rule "MD034" # no raw url +rule "MD040" # Fenced code blocks should have a language specified +rule "MD046", :style => :fenced # code block style - fenced diff --git a/config/spelling_ignorelines.txt b/config/spelling_ignorelines.txt new file mode 100644 index 0000000..a4a56df --- /dev/null +++ b/config/spelling_ignorelines.txt @@ -0,0 +1 @@ +- [Parth Bansal](https://github.com/parthb83) diff --git a/config/spelling_whitelist.txt b/config/spelling_whitelist.txt new file mode 100644 index 0000000..2e91d0e --- /dev/null +++ b/config/spelling_whitelist.txt @@ -0,0 +1,9 @@ +ans +te +stoll +endwhile +fo +emiss +ist +copyable +dur From 8fc657e90bdf028da79814fe30835e76c15f46ee Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 26 Sep 2024 13:34:23 +0000 Subject: [PATCH 5/8] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- README.md | 10 +- helics_federate.c | 176 +++++++++++------------ helics_input.c | 327 +++++++++++++++++++------------------------ helics_publication.c | 292 +++++++++++++++++--------------------- 4 files changed, 366 insertions(+), 439 deletions(-) diff --git a/README.md b/README.md index eb4b7e7..9d9b8a6 100644 --- a/README.md +++ b/README.md @@ -27,14 +27,14 @@ this will generate the helics interface in a folder 1 level above the simHELICS >> buildSimHELICS(); ``` -The `buildSimHELICS` function also has an option to generate the package file. This can be used to generate a package that can be transfered to a similar system. +The `buildSimHELICS` function also has an option to generate the package file. This can be used to generate a package that can be transferred to a similar system. This is a new process for building a simulink interface, it is tested but not extensively and not on a large variety of platforms if you run into issues please let us know. ### Requirements Matlab 2018a or greater. -intalled compatible compiler to build the mex file +installed compatible compiler to build the mex file ### building with custom HELICS version @@ -53,17 +53,17 @@ These simulink blocks are in a simHELICS.slx library object and can be loaded or ### federate block -The federate block takes 1 parameter which is the name of a config file. This config file is typically json, but other formats including a direct string input is allowed. This configuration json is the only means of configuring the federate in simulink. All interfaces should be specified in this configuraiton file. +The federate block takes 1 parameter which is the name of a config file. This config file is typically json, but other formats including a direct string input is allowed. This configuration json is the only means of configuring the federate in simulink. All interfaces should be specified in this configuration file. ### input block -The input block is used to retreive data from HELICS. It takes two parameters. The first is an integer or string with the input index(zero based) or name resepectively, and some arguments as a string as the second argument. Allowed arguments are 'output_size=X', and 'output_type=XXXX'. These define the size and type of the simulink output on the block. Default for an empty string is 1, and double. 'double','int', 'bool', and 'complex' are supported along with 'vector' and 'complex_vector'. The HELICS interface type is defined in the configuration. This is defining the desired output type in simulink. +The input block is used to retrieve data from HELICS. It takes two parameters. The first is an integer or string with the input index(zero based) or name respectively, and some arguments as a string as the second argument. Allowed arguments are 'output_size=X', and 'output_type=XXXX'. These define the size and type of the simulink output on the block. Default for an empty string is 1, and double. 'double','int', 'bool', and 'complex' are supported along with 'vector' and 'complex_vector'. The HELICS interface type is defined in the configuration. This is defining the desired output type in simulink. The input_block is wired to the helics_federate block. ### Publication block -The publication block is used to send data via HELICS. The first is an integer or string with the publication index(zero based) or name resepectively, and some arguments as a string as the second argument. Allowed arguments are 'input_size=X', and 'input_type=XXXX'. These define the size and type of the second simulink input on the block. Default for an empty string argument is 1, and double. 'double','int', 'bool', and 'complex' are supported along with 'vector' and 'complex_vector'. The HELICS interface type is defined in the configuration. This is defining the desired input type and size in simulink. +The publication block is used to send data via HELICS. The first is an integer or string with the publication index(zero based) or name respectively, and some arguments as a string as the second argument. Allowed arguments are 'input_size=X', and 'input_type=XXXX'. These define the size and type of the second simulink input on the block. Default for an empty string argument is 1, and double. 'double','int', 'bool', and 'complex' are supported along with 'vector' and 'complex_vector'. The HELICS interface type is defined in the configuration. This is defining the desired input type and size in simulink. The publication is block is wired to the helics_federate block and the data wishing to be published. diff --git a/helics_federate.c b/helics_federate.c index 5e34547..d4dda02 100644 --- a/helics_federate.c +++ b/helics_federate.c @@ -7,129 +7,119 @@ #define S_FUNCTION_NAME helics_federate /* Defines and Includes */ #define S_FUNCTION_LEVEL 2 - -#include "simstruc.h" #include "helics/helics.h" #include "math.h" +#include "simstruc.h" -static void mdlInitializeSizes(SimStruct *S) -{ - ssSetNumSFcnParams(S, 1); - if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) { - return; /* Parameter mismatch reported by the Simulink engine*/ - } - - if (!ssSetNumInputPorts(S, 0)) return; +static void mdlInitializeSizes(SimStruct *S) { + ssSetNumSFcnParams(S, 1); + if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) { + return; /* Parameter mismatch reported by the Simulink engine*/ + } - if (!ssSetNumOutputPorts(S,1)) return; - ssSetOutputPortWidth(S, 0, 3); - ssSetOutputPortDataType(S,0,SS_DOUBLE); + if (!ssSetNumInputPorts(S, 0)) + return; - ssSetNumSampleTimes(S, 1); + if (!ssSetNumOutputPorts(S, 1)) + return; + ssSetOutputPortWidth(S, 0, 3); + ssSetOutputPortDataType(S, 0, SS_DOUBLE); + ssSetNumSampleTimes(S, 1); - /* Set this S-function as runtime thread-safe for multicore execution */ - ssSetRuntimeThreadSafetyCompliance(S, RUNTIME_THREAD_SAFETY_COMPLIANCE_TRUE); - ssSetOptions(S,SS_OPTION_CALL_TERMINATE_ON_EXIT); + /* Set this S-function as runtime thread-safe for multicore execution */ + ssSetRuntimeThreadSafetyCompliance(S, RUNTIME_THREAD_SAFETY_COMPLIANCE_TRUE); + ssSetOptions(S, SS_OPTION_CALL_TERMINATE_ON_EXIT); - ssSetNumDWork(S,2); - ssSetDWorkDataType(S, 0, SS_DOUBLE); - ssSetDWorkDataType(S, 1, SS_BOOLEAN); - ssSetDWorkName(S,0,"timing"); - ssSetDWorkName(S,1,"control"); - ssSetDWorkWidth(S, 0, 3); - ssSetDWorkWidth(S, 1, 2); + ssSetNumDWork(S, 2); + ssSetDWorkDataType(S, 0, SS_DOUBLE); + ssSetDWorkDataType(S, 1, SS_BOOLEAN); + ssSetDWorkName(S, 0, "timing"); + ssSetDWorkName(S, 1, "control"); + ssSetDWorkWidth(S, 0, 3); + ssSetDWorkWidth(S, 1, 2); } -static void mdlInitializeSampleTimes(SimStruct *S) -{ +static void mdlInitializeSampleTimes(SimStruct *S) { - ssSetSampleTime(S, 0, VARIABLE_SAMPLE_TIME); + ssSetSampleTime(S, 0, VARIABLE_SAMPLE_TIME); } #define MDL_GET_TIME_OF_NEXT_VAR_HIT -static void mdlGetTimeOfNextVarHit(SimStruct *S) - { - real_T *timing = (real_T*) ssGetDWork(S,0); - time_T timeOfNextHit = timing[0] + timing[2]; - ssSetTNext(S, timeOfNextHit); - } +static void mdlGetTimeOfNextVarHit(SimStruct *S) { + real_T *timing = (real_T *)ssGetDWork(S, 0); + time_T timeOfNextHit = timing[0] + timing[2]; + ssSetTNext(S, timeOfNextHit); +} #define MDL_START -void mdlStart(SimStruct *S) -{ - const mxArray *file_name_param=ssGetSFcnParam(S, 0); - char *file_name=mxArrayToString(file_name_param); - - ssPrintf("trying to load file %s\n",file_name); - HelicsError error= helicsErrorInitialize(); - HelicsFederate fed= helicsCreateCombinationFederateFromConfig(file_name,&error); - - if (helicsFederateIsValid(fed)) - { - ssPrintf("loaded Federate %s\n",helicsFederateGetName(fed)); - } - SimStruct *root_ss=ssGetRootSS(S); - ssSetUserData(root_ss,fed); - helicsFederateEnterInitializingMode(fed,NULL); - real_T *timing = (real_T*) ssGetDWork(S,0); - timing[0]=-1.0; - timing[2]=helicsFederateGetTimeProperty(fed,HELICS_PROPERTY_TIME_PERIOD,NULL); - ssPrintf("time period = %f\n",timing[2]); -} +void mdlStart(SimStruct *S) { + const mxArray *file_name_param = ssGetSFcnParam(S, 0); + char *file_name = mxArrayToString(file_name_param); + + ssPrintf("trying to load file %s\n", file_name); + HelicsError error = helicsErrorInitialize(); + HelicsFederate fed = + helicsCreateCombinationFederateFromConfig(file_name, &error); + if (helicsFederateIsValid(fed)) { + ssPrintf("loaded Federate %s\n", helicsFederateGetName(fed)); + } + SimStruct *root_ss = ssGetRootSS(S); + ssSetUserData(root_ss, fed); + helicsFederateEnterInitializingMode(fed, NULL); + real_T *timing = (real_T *)ssGetDWork(S, 0); + timing[0] = -1.0; + timing[2] = + helicsFederateGetTimeProperty(fed, HELICS_PROPERTY_TIME_PERIOD, NULL); + ssPrintf("time period = %f\n", timing[2]); +} #define MDL_INITIALIZE_CONDITIONS -void mdlInitializeConditions(SimStruct *S) -{ - SimStruct *root_ss=ssGetRootSS(S); - HelicsFederate fed=ssGetUserData(root_ss); - helicsFederateEnterExecutingMode(fed,NULL); - real_T *timing = (real_T*) ssGetDWork(S,0); - timing[0]=0.0; +void mdlInitializeConditions(SimStruct *S) { + SimStruct *root_ss = ssGetRootSS(S); + HelicsFederate fed = ssGetUserData(root_ss); + helicsFederateEnterExecutingMode(fed, NULL); + real_T *timing = (real_T *)ssGetDWork(S, 0); + timing[0] = 0.0; } -static void mdlOutputs(SimStruct *S, int_T tid) -{ - int_T i; - time_T time=ssGetT(S); - real_T *y = ssGetOutputPortRealSignal(S,0); - int_T width = ssGetOutputPortWidth(S,0); - - real_T *timing = (real_T*) ssGetDWork(S,0); - *y++ = timing[0]; - for (i=1; i -static void mdlInitializeSizes(SimStruct *S) -{ - ssSetNumSFcnParams(S, 2); - if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) { - return; /* Parameter mismatch reported by the Simulink engine*/ - } - - if (!ssSetNumInputPorts(S, 1)) return; - ssSetInputPortWidth(S,0,3); - - ssSetInputPortDataType(S, 0, SS_DOUBLE ); - - if (!ssSetNumOutputPorts(S,1)) return; - const mxArray *params=ssGetSFcnParam(S, 1); - char *param_string=mxArrayToString(params); - int output_width=1; - int dataType=HELICS_DATA_TYPE_DOUBLE; - - char *token=NULL; - token=strtok(param_string," ,"); - while (token){ - ssPrintf("got token %s\n",token); - if (strncmp(token,"output_size=",12)==0) - { - output_width=atoi(token+12); - ssPrintf("got token output_size read as %s converted to %d\n",token+12,output_width); - } - else if (strncmp(token,"output_type=",12)==0) - { - dataType=helicsGetDataType(token+12); - ssPrintf("got token output_type read as %s converted to %d\n",token+12,dataType); - - } - token=strtok(NULL," ,"); - } - ssSetOutputPortWidth(S, 0, output_width); - switch (dataType) - { - case HELICS_DATA_TYPE_DOUBLE: case HELICS_DATA_TYPE_VECTOR: - ssSetOutputPortDataType(S, 0, SS_DOUBLE); - break; - case HELICS_DATA_TYPE_INT: - ssSetOutputPortDataType(S, 0, SS_INT32); - break; - case HELICS_DATA_TYPE_BOOLEAN: - ssSetOutputPortDataType(S, 0, SS_BOOLEAN); - break; - case HELICS_DATA_TYPE_COMPLEX: case HELICS_DATA_TYPE_COMPLEX_VECTOR: - ssSetOutputPortDataType(S, 0, SS_DOUBLE); - //something with complex indications - break; +static void mdlInitializeSizes(SimStruct *S) { + ssSetNumSFcnParams(S, 2); + if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) { + return; /* Parameter mismatch reported by the Simulink engine*/ + } + + if (!ssSetNumInputPorts(S, 1)) + return; + ssSetInputPortWidth(S, 0, 3); + + ssSetInputPortDataType(S, 0, SS_DOUBLE); + + if (!ssSetNumOutputPorts(S, 1)) + return; + const mxArray *params = ssGetSFcnParam(S, 1); + char *param_string = mxArrayToString(params); + int output_width = 1; + int dataType = HELICS_DATA_TYPE_DOUBLE; + + char *token = NULL; + token = strtok(param_string, " ,"); + while (token) { + ssPrintf("got token %s\n", token); + if (strncmp(token, "output_size=", 12) == 0) { + output_width = atoi(token + 12); + ssPrintf("got token output_size read as %s converted to %d\n", token + 12, + output_width); + } else if (strncmp(token, "output_type=", 12) == 0) { + dataType = helicsGetDataType(token + 12); + ssPrintf("got token output_type read as %s converted to %d\n", token + 12, + dataType); } - - ssSetInputPortRequiredContiguous(S,0,1); - /* sample times */ - ssSetNumSampleTimes( S, 1 ); - /* Set this S-function as runtime thread-safe for multicore execution */ - ssSetRuntimeThreadSafetyCompliance(S, RUNTIME_THREAD_SAFETY_COMPLIANCE_TRUE); - ssSetOptions(S,SS_OPTION_CALL_TERMINATE_ON_EXIT); + token = strtok(NULL, " ,"); + } + ssSetOutputPortWidth(S, 0, output_width); + switch (dataType) { + case HELICS_DATA_TYPE_DOUBLE: + case HELICS_DATA_TYPE_VECTOR: + ssSetOutputPortDataType(S, 0, SS_DOUBLE); + break; + case HELICS_DATA_TYPE_INT: + ssSetOutputPortDataType(S, 0, SS_INT32); + break; + case HELICS_DATA_TYPE_BOOLEAN: + ssSetOutputPortDataType(S, 0, SS_BOOLEAN); + break; + case HELICS_DATA_TYPE_COMPLEX: + case HELICS_DATA_TYPE_COMPLEX_VECTOR: + ssSetOutputPortDataType(S, 0, SS_DOUBLE); + // something with complex indications + break; + } + + ssSetInputPortRequiredContiguous(S, 0, 1); + /* sample times */ + ssSetNumSampleTimes(S, 1); + /* Set this S-function as runtime thread-safe for multicore execution */ + ssSetRuntimeThreadSafetyCompliance(S, RUNTIME_THREAD_SAFETY_COMPLIANCE_TRUE); + ssSetOptions(S, SS_OPTION_CALL_TERMINATE_ON_EXIT); } -static void mdlInitializeSampleTimes(SimStruct *S) -{ - ssSetSampleTime( S, 0, INHERITED_SAMPLE_TIME ); - ssSetOffsetTime( S, 0, FIXED_IN_MINOR_STEP_OFFSET ); - ssSetModelReferenceSampleTimeDefaultInheritance(S); +static void mdlInitializeSampleTimes(SimStruct *S) { + ssSetSampleTime(S, 0, INHERITED_SAMPLE_TIME); + ssSetOffsetTime(S, 0, FIXED_IN_MINOR_STEP_OFFSET); + ssSetModelReferenceSampleTimeDefaultInheritance(S); } #define MDL_START -void mdlStart(SimStruct *S) -{ - - -} - +void mdlStart(SimStruct *S) {} #define MDL_INITIALIZE_CONDITIONS -void mdlInitializeConditions(SimStruct *S) -{ - SimStruct *root_ss=ssGetRootSS(S); - HelicsFederate fed=ssGetUserData(root_ss); - if (!helicsFederateIsValid(fed)){ - ssPrintf("HELICS federate is not valid\n"); - ssSetErrorStatus(S,"HELICS federate is not valid"); - return; - } - - - const mxArray *index_param=ssGetSFcnParam(S, 0); - mxClassID paramType=mxGetClassID(index_param); - HelicsInput inp; - switch (paramType) - { - case mxCHAR_CLASS: - { - char *input_name=mxArrayToString(index_param); - HelicsError err=helicsErrorInitialize(); - inp=helicsFederateGetInput(fed,input_name,&err); - if (err.error_code!=HELICS_OK) - { - ssSetErrorStatus(S,err.message); - return; - }} - break; - case mxDOUBLE_CLASS: - { - double input_index=mxGetScalar(index_param); - HelicsError err=helicsErrorInitialize(); - inp=helicsFederateGetInputByIndex(fed,(int32_t)(input_index),&err); - if (err.error_code!=HELICS_OK) - { - ssSetErrorStatus(S,err.message); - return; - } - } - break; +void mdlInitializeConditions(SimStruct *S) { + SimStruct *root_ss = ssGetRootSS(S); + HelicsFederate fed = ssGetUserData(root_ss); + if (!helicsFederateIsValid(fed)) { + ssPrintf("HELICS federate is not valid\n"); + ssSetErrorStatus(S, "HELICS federate is not valid"); + return; + } + + const mxArray *index_param = ssGetSFcnParam(S, 0); + mxClassID paramType = mxGetClassID(index_param); + HelicsInput inp; + switch (paramType) { + case mxCHAR_CLASS: { + char *input_name = mxArrayToString(index_param); + HelicsError err = helicsErrorInitialize(); + inp = helicsFederateGetInput(fed, input_name, &err); + if (err.error_code != HELICS_OK) { + ssSetErrorStatus(S, err.message); + return; } - ssPrintf("Got input name %s\n",helicsInputGetName(inp)); - ssSetUserData(S,inp); -} - -static void mdlOutputs(SimStruct *S, int_T tid) -{ - HelicsInput inp=ssGetUserData(S); - - DTypeId outputDataType = ssGetOutputPortDataType(S, 0); - int width=ssGetOutputPortWidth(S,0); - - switch(outputDataType){ - case SS_UINT8: - case SS_INT8: - break; - case SS_UINT16: - case SS_UINT32: - case SS_INT16: - case SS_INT32: - break; - case SS_DOUBLE: - case SS_SINGLE: - { - if (helicsGetDataType(helicsInputGetType(inp))==HELICS_DATA_TYPE_COMPLEX) - { - - } - else if (width>1) - { - ssPrintf("input input width =%d\n",width); - real_T *y = ssGetOutputPortRealSignal(S,0); - int sz; - HelicsError err=helicsErrorInitialize(); - helicsInputGetVector(inp,y,width,&sz,&err); - ssPrintf("got input size %d input[0]=%f",sz,y[0]); - if (err.error_code!=HELICS_OK) - { - - } - else - { - if (sz 1) { + ssPrintf("input input width =%d\n", width); + real_T *y = ssGetOutputPortRealSignal(S, 0); + int sz; + HelicsError err = helicsErrorInitialize(); + helicsInputGetVector(inp, y, width, &sz, &err); + ssPrintf("got input size %d input[0]=%f", sz, y[0]); + if (err.error_code != HELICS_OK) { + + } else { + if (sz < width) { + int ii = 0; + for (ii = sz; ii < width; ++ii) { + y[ii] = HELICS_INVALID_PROPERTY_VALUE; + } + } + } + } else { + ssPrintf("input input width =%d\n", width); + double val = helicsInputGetDouble(inp, NULL); + real_T *y = ssGetOutputPortRealSignal(S, 0); + y[0] = val; + } + } break; + case SS_BOOLEAN: + break; + } } -static void mdlTerminate(SimStruct *S) -{ - - -} +#define MDL_UPDATE +void mdlUpdate(SimStruct *S, int_T tid) {} +static void mdlTerminate(SimStruct *S) {} #include "simulink.c" /* MEX-file interface mechanism */ diff --git a/helics_publication.c b/helics_publication.c index 4a77226..6a11ec4 100644 --- a/helics_publication.c +++ b/helics_publication.c @@ -7,183 +7,155 @@ #define S_FUNCTION_NAME helics_publication /* Defines and Includes */ #define S_FUNCTION_LEVEL 2 - - -#include "simstruc.h" #include "helics/helics.h" #include "math.h" +#include "simstruc.h" -static void mdlInitializeSizes(SimStruct *S) -{ - ssSetNumSFcnParams(S, 2); - if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) { - return; /* Parameter mismatch reported by the Simulink engine*/ - } - - if (!ssSetNumInputPorts(S, 2)) return; - ssSetInputPortWidth(S,0,3); - - ssSetInputPortDataType(S, 0, SS_DOUBLE ); - - const mxArray *params=ssGetSFcnParam(S, 1); - char *param_string=mxArrayToString(params); - ssPrintf("pub parameter string=%s\n",param_string); - - int input_width=1; - int dataType=HELICS_DATA_TYPE_DOUBLE; - - char *token=NULL; - token=strtok(param_string," ,"); - while (token){ - ssPrintf("got token %s\n",token); - if (strncmp(token,"input_size=",11)==0) - { - input_width=atoi(token+11); - ssPrintf("got token input_size read as %s converted to %d\n",token+11,input_width); - } - else if (strncmp(token,"input_type=",11)==0) - { - dataType=helicsGetDataType(token+11); - ssPrintf("got token input_type read as %s converted to %d\n",token+11,dataType); - - } - token=strtok(NULL," ,"); - } - ssSetInputPortWidth(S, 1, input_width); - switch (dataType) - { - case HELICS_DATA_TYPE_DOUBLE: case HELICS_DATA_TYPE_VECTOR: - ssSetInputPortDataType(S, 1, SS_DOUBLE); - break; - case HELICS_DATA_TYPE_INT: - ssSetInputPortDataType(S, 1, SS_INT32); - break; - case HELICS_DATA_TYPE_BOOLEAN: - ssSetInputPortDataType(S, 1, SS_BOOLEAN); - break; - case HELICS_DATA_TYPE_COMPLEX: case HELICS_DATA_TYPE_COMPLEX_VECTOR: - ssSetInputPortDataType(S, 1, SS_DOUBLE); - //something with complex indications - break; - case HELICS_DATA_TYPE_STRING: - ssSetInputPortDataType(S,1,SS_UINT8); - break; - +static void mdlInitializeSizes(SimStruct *S) { + ssSetNumSFcnParams(S, 2); + if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) { + return; /* Parameter mismatch reported by the Simulink engine*/ + } + + if (!ssSetNumInputPorts(S, 2)) + return; + ssSetInputPortWidth(S, 0, 3); + + ssSetInputPortDataType(S, 0, SS_DOUBLE); + + const mxArray *params = ssGetSFcnParam(S, 1); + char *param_string = mxArrayToString(params); + ssPrintf("pub parameter string=%s\n", param_string); + + int input_width = 1; + int dataType = HELICS_DATA_TYPE_DOUBLE; + + char *token = NULL; + token = strtok(param_string, " ,"); + while (token) { + ssPrintf("got token %s\n", token); + if (strncmp(token, "input_size=", 11) == 0) { + input_width = atoi(token + 11); + ssPrintf("got token input_size read as %s converted to %d\n", token + 11, + input_width); + } else if (strncmp(token, "input_type=", 11) == 0) { + dataType = helicsGetDataType(token + 11); + ssPrintf("got token input_type read as %s converted to %d\n", token + 11, + dataType); } - ssSetInputPortRequiredContiguous(S,0,1); - ssSetInputPortRequiredContiguous(S,1,1); - if (!ssSetNumOutputPorts(S,0)) return; - - /* sample times */ - ssSetNumSampleTimes( S, 1 ); - /* Set this S-function as runtime thread-safe for multicore execution */ - ssSetRuntimeThreadSafetyCompliance(S, RUNTIME_THREAD_SAFETY_COMPLIANCE_TRUE); - ssSetOptions(S,SS_OPTION_CALL_TERMINATE_ON_EXIT); + token = strtok(NULL, " ,"); + } + ssSetInputPortWidth(S, 1, input_width); + switch (dataType) { + case HELICS_DATA_TYPE_DOUBLE: + case HELICS_DATA_TYPE_VECTOR: + ssSetInputPortDataType(S, 1, SS_DOUBLE); + break; + case HELICS_DATA_TYPE_INT: + ssSetInputPortDataType(S, 1, SS_INT32); + break; + case HELICS_DATA_TYPE_BOOLEAN: + ssSetInputPortDataType(S, 1, SS_BOOLEAN); + break; + case HELICS_DATA_TYPE_COMPLEX: + case HELICS_DATA_TYPE_COMPLEX_VECTOR: + ssSetInputPortDataType(S, 1, SS_DOUBLE); + // something with complex indications + break; + case HELICS_DATA_TYPE_STRING: + ssSetInputPortDataType(S, 1, SS_UINT8); + break; + } + ssSetInputPortRequiredContiguous(S, 0, 1); + ssSetInputPortRequiredContiguous(S, 1, 1); + if (!ssSetNumOutputPorts(S, 0)) + return; + + /* sample times */ + ssSetNumSampleTimes(S, 1); + /* Set this S-function as runtime thread-safe for multicore execution */ + ssSetRuntimeThreadSafetyCompliance(S, RUNTIME_THREAD_SAFETY_COMPLIANCE_TRUE); + ssSetOptions(S, SS_OPTION_CALL_TERMINATE_ON_EXIT); } -static void mdlInitializeSampleTimes(SimStruct *S) -{ - ssSetSampleTime( S, 0, INHERITED_SAMPLE_TIME ); - ssSetOffsetTime( S, 0, FIXED_IN_MINOR_STEP_OFFSET ); - ssSetModelReferenceSampleTimeDefaultInheritance(S); +static void mdlInitializeSampleTimes(SimStruct *S) { + ssSetSampleTime(S, 0, INHERITED_SAMPLE_TIME); + ssSetOffsetTime(S, 0, FIXED_IN_MINOR_STEP_OFFSET); + ssSetModelReferenceSampleTimeDefaultInheritance(S); } #define MDL_START -void mdlStart(SimStruct *S) -{ - -} - +void mdlStart(SimStruct *S) {} #define MDL_INITIALIZE_CONDITIONS -void mdlInitializeConditions(SimStruct *S) -{ - - SimStruct *root_ss=ssGetRootSS(S); - HelicsFederate fed=ssGetUserData(root_ss); - if (!helicsFederateIsValid(fed)){ - ssPrintf("Helics federate for publication is not valid\n"); - ssSetErrorStatus(S,"HELICS federate is not valid"); - return; - } - - - const mxArray *index_param=ssGetSFcnParam(S, 0); - mxClassID paramType=mxGetClassID(index_param); - HelicsPublication pub; - switch (paramType) - { - case mxCHAR_CLASS: - { - char *pub_name=mxArrayToString(index_param); - HelicsError err=helicsErrorInitialize(); - pub=helicsFederateGetPublication(fed,pub_name,&err); - if (err.error_code!=HELICS_OK) - { - ssSetErrorStatus(S,err.message); - return; - }} - break; - case mxDOUBLE_CLASS: - { - double pub_index=mxGetScalar(index_param); - HelicsError err=helicsErrorInitialize(); - pub=helicsFederateGetPublicationByIndex(fed,(int32_t)(pub_index),&err); - if (err.error_code!=HELICS_OK) - { - ssSetErrorStatus(S,err.message); - return; - } - } - break; +void mdlInitializeConditions(SimStruct *S) { + + SimStruct *root_ss = ssGetRootSS(S); + HelicsFederate fed = ssGetUserData(root_ss); + if (!helicsFederateIsValid(fed)) { + ssPrintf("Helics federate for publication is not valid\n"); + ssSetErrorStatus(S, "HELICS federate is not valid"); + return; + } + + const mxArray *index_param = ssGetSFcnParam(S, 0); + mxClassID paramType = mxGetClassID(index_param); + HelicsPublication pub; + switch (paramType) { + case mxCHAR_CLASS: { + char *pub_name = mxArrayToString(index_param); + HelicsError err = helicsErrorInitialize(); + pub = helicsFederateGetPublication(fed, pub_name, &err); + if (err.error_code != HELICS_OK) { + ssSetErrorStatus(S, err.message); + return; } - ssPrintf("Got publication name %s\n",helicsPublicationGetName(pub)); - ssSetUserData(S,pub); - -} - -static void mdlOutputs(SimStruct *S, int_T tid) -{ - -} - -#define MDL_UPDATE -void mdlUpdate(SimStruct *S, int_T tid) -{ - HelicsPublication pub=ssGetUserData(S); - - const double *tsig=ssGetInputPortRealSignal(S,0); - - DTypeId inputDataType = ssGetInputPortDataType(S, 1); - switch(inputDataType){ - case SS_UINT8: - case SS_INT8: - break; - case SS_UINT16: - case SS_UINT32: - case SS_INT16: - case SS_INT32: - break; - case SS_DOUBLE: - case SS_SINGLE: - { - const double *sig = ssGetInputPortRealSignal(S,1); - ssPrintf("publishing double %f\n",sig[0]-1.0); - - helicsPublicationPublishDouble(pub,sig[0]-1.0,NULL); - ssPrintf("published double\n"); - } - break; - case SS_BOOLEAN: - break; + } break; + case mxDOUBLE_CLASS: { + double pub_index = mxGetScalar(index_param); + HelicsError err = helicsErrorInitialize(); + pub = helicsFederateGetPublicationByIndex(fed, (int32_t)(pub_index), &err); + if (err.error_code != HELICS_OK) { + ssSetErrorStatus(S, err.message); + return; } + } break; + } + ssPrintf("Got publication name %s\n", helicsPublicationGetName(pub)); + ssSetUserData(S, pub); } -static void mdlTerminate(SimStruct *S) -{ - +static void mdlOutputs(SimStruct *S, int_T tid) {} +#define MDL_UPDATE +void mdlUpdate(SimStruct *S, int_T tid) { + HelicsPublication pub = ssGetUserData(S); + + const double *tsig = ssGetInputPortRealSignal(S, 0); + + DTypeId inputDataType = ssGetInputPortDataType(S, 1); + switch (inputDataType) { + case SS_UINT8: + case SS_INT8: + break; + case SS_UINT16: + case SS_UINT32: + case SS_INT16: + case SS_INT32: + break; + case SS_DOUBLE: + case SS_SINGLE: { + const double *sig = ssGetInputPortRealSignal(S, 1); + ssPrintf("publishing double %f\n", sig[0] - 1.0); + + helicsPublicationPublishDouble(pub, sig[0] - 1.0, NULL); + ssPrintf("published double\n"); + } break; + case SS_BOOLEAN: + break; + } } +static void mdlTerminate(SimStruct *S) {} #include "simulink.c" /* MEX-file interface mechanism */ From f6e9eae2d4fa1e8794d0a2cd44bba4d36c53b882 Mon Sep 17 00:00:00 2001 From: Philip Top Date: Thu, 26 Sep 2024 07:19:35 -0700 Subject: [PATCH 6/8] fix url --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index eb4b7e7..aee88ac 100644 --- a/README.md +++ b/README.md @@ -79,12 +79,12 @@ Versions prior to Matlab 2015 will require more extensive modifications. And may ## Source Repo -The simHelics source code is hosted on GitHub: [https://github.com/GMLC-TDC/simHelics](https://github.com/GMLC-TDC/simHELICS) \[This may not be accurate\] +The simHELICS source code is hosted on GitHub: [https://github.com/GMLC-TDC/simHelics](https://github.com/GMLC-TDC/simHELICS) ## Citation General citation for HELICS: -T. Hardy, B. Palmintier, P. Top, D. Krishnamurthy and J. Fuller, "HELICS: A Co-Simulation Framework for Scalable Multi-Domain Modeling and Analysis," in IEEE Access, doi: 10.1109/ACCESS.2024.3363615, available at [https://ieeexplore.ieee.org/document/10424422](https://ieeexplore.ieee.org/document/10424422/ +T. Hardy, B. Palmintier, P. Top, D. Krishnamurthy and J. Fuller, "HELICS: A Co-Simulation Framework for Scalable Multi-Domain Modeling and Analysis," in IEEE Access, doi: 10.1109/ACCESS.2024.3363615, available at [](https://ieeexplore.ieee.org/document/10424422/ ## Release From 6327885ac2d1abee163dca83c04acdb4e8c1ae30 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 26 Sep 2024 14:20:16 +0000 Subject: [PATCH 7/8] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cf7788c..138839f 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ Versions prior to Matlab 2015 will require more extensive modifications. And may ## Source Repo -The simHELICS source code is hosted on GitHub: [https://github.com/GMLC-TDC/simHelics](https://github.com/GMLC-TDC/simHELICS) +The simHELICS source code is hosted on GitHub: [https://github.com/GMLC-TDC/simHelics](https://github.com/GMLC-TDC/simHELICS) ## Citation From 7d6b127991352a0497939bb674ca4018fa3bf39e Mon Sep 17 00:00:00 2001 From: Philip Top Date: Thu, 26 Sep 2024 07:28:58 -0700 Subject: [PATCH 8/8] fix link in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cf7788c..38fd704 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,7 @@ The simHELICS source code is hosted on GitHub: [https://github.com/GMLC-TDC/simH ## Citation General citation for HELICS: -T. Hardy, B. Palmintier, P. Top, D. Krishnamurthy and J. Fuller, "HELICS: A Co-Simulation Framework for Scalable Multi-Domain Modeling and Analysis," in IEEE Access, doi: 10.1109/ACCESS.2024.3363615, available at [](https://ieeexplore.ieee.org/document/10424422/ +T. Hardy, B. Palmintier, P. Top, D. Krishnamurthy and J. Fuller, "HELICS: A Co-Simulation Framework for Scalable Multi-Domain Modeling and Analysis," in IEEE Access, doi: 10.1109/ACCESS.2024.3363615, available at [](https://ieeexplore.ieee.org/document/10424422/) ## Release