diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b17a4a1cac..f4234708e8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,17 +22,19 @@ jobs: - name: 'Windows static - C++' os: windows-latest python_bindings: OFF - additional_cmake_options: -DLibXml2_DIR="C:\libxml2\libxml2-2.9.10\CMake" -DZLIB_DIR="C:\zlib\lib\cmake\ZLIB-1.2.12" + additional_cmake_options: -DLibXml2_DIR="C:\libxml2\libxml2-2.9.10\CMake" -DSYMENGINE_DIR="C:\symengine\CMake" -DZLIB_DIR="C:\zlib\lib\cmake\ZLIB-1.2.12" - name: 'Windows shared - C++/Python' os: windows-latest python_bindings: ON - additional_cmake_options: -DLibXml2_DIR="C:\libxml2\libxml2-2.9.10\CMake" -DZLIB_DIR="C:\zlib\lib\cmake\ZLIB-1.2.12" + additional_cmake_options: -DLibXml2_DIR="C:\libxml2\libxml2-2.9.10\CMake" -DSYMENGINE_DIR="C:\symengine\CMake" -DZLIB_DIR="C:\zlib\lib\cmake\ZLIB-1.2.12" - name: 'Linux static - C++' os: ubuntu-latest python_bindings: OFF + additional_cmake_options: -DSYMENGINE_DIR="$HOME/symengine/build/cmake" - name: 'Linux shared - C++/Python' os: ubuntu-latest python_bindings: ON + additional_cmake_options: -DSYMENGINE_DIR="$HOME/symengine/build/cmake" - name: 'macOS static - C++ (Intel)' os: macos-15-intel python_bindings: OFF @@ -68,6 +70,23 @@ jobs: cd C:\ curl -L https://github.com/cellml/gha/releases/download/gha/libxml2-Windows.tar.gz -o libxml2.tar.gz -s tar -xzf libxml2.tar.gz + - name: Install SymEngine (Windows only) + if: ${{ runner.os == 'Windows' }} + run: | + cd C:\ + curl -L https://github.com/cellml/gha/releases/download/gha/symengine-Windows.tar.gz -o symengine.tar.gz -s + tar -xzf symengine.tar.gz + - name: Install SymEngine (Linux only) + if: ${{ runner.os == 'Linux' }} + run: | + cd $HOME + curl -L https://github.com/cellml/gha/releases/download/gha/symengine-Linux.tar.gz -o symengine.tar.gz -s + tar -xzf symengine.tar.gz + - name: Install SymEngine (macOS only) + if: ${{ runner.os == 'macOS' }} + run: | + brew update + brew install symengine - name: Install zlib (Windows only) if: ${{ runner.os == 'Windows' }} run: | @@ -101,13 +120,17 @@ jobs: run: | cd $HOME wget https://github.com/cellml/gha/releases/download/gha/libxml2-WASM.tar.gz -O - | tar -xz + - name: Install SymEngine + run: | + cd $HOME + wget https://github.com/cellml/gha/releases/download/gha/symengine-WASM.tar.gz -O - | tar -xz - name: Install zlib run: | cd $HOME wget https://github.com/cellml/gha/releases/download/gha/zlib-WASM.tar.gz -O - | tar -xz - name: Configure libCellML run: | - emcmake cmake -G Ninja -S . -B build-wasm -DBUILD_TYPE=Release -DLIBXML2_INCLUDE_DIR=$HOME/libxml2/include/libxml2 -DLIBXML2_LIBRARY=$HOME/libxml2/lib/libxml2.a -DZLIB_INCLUDE_DIR=$HOME/zlib/include -DZLIB_LIBRARY=$HOME/zlib/lib/libz.a + emcmake cmake -G Ninja -S . -B build-wasm -DBUILD_TYPE=Release -DLIBXML2_INCLUDE_DIR=$HOME/libxml2/include/libxml2 -DLIBXML2_LIBRARY=$HOME/libxml2/lib/libxml2.a -DSYMENGINE_INCLUDE_DIR=$HOME/symengine/include -DSYMENGINE_LIBRARY=$HOME/symengine/lib/libsymengine.a -DZLIB_INCLUDE_DIR=$HOME/zlib/include -DZLIB_LIBRARY=$HOME/zlib/lib/libz.a - name: Build libCellML run: cmake --build build-wasm - name: Unit testing diff --git a/cmake/environmentchecks.cmake b/cmake/environmentchecks.cmake index 260b5c0ae4..6409daaa02 100644 --- a/cmake/environmentchecks.cmake +++ b/cmake/environmentchecks.cmake @@ -183,6 +183,13 @@ if(NOT DEFINED _ZLIB_FIND_REPORTED) message(STATUS "Found ZLIB: ${ZLIB_LIBRARIES} (found version \"${ZLIB_VERSION_STRING}\").") endif() +# Set the minimum policy version to work around SymEngine's outdated CMake requirements. +set(CMAKE_POLICY_VERSION_MINIMUM 3.10) + +# Find SymEngine. +find_package(SymEngine REQUIRED CONFIG) +message(STATUS "Found SymEngine: ${SYMENGINE_LIBRARIES} (found version \"${SymEngine_VERSION}\").") + if(BUILDCACHE_EXE OR CLCACHE_EXE OR CCACHE_EXE) set(COMPILER_CACHE_AVAILABLE TRUE CACHE INTERNAL "Executable required to cache compilations.") endif() diff --git a/src/3rdparty/symengine/symenginebegin.h b/src/3rdparty/symengine/symenginebegin.h new file mode 100644 index 0000000000..7251c1d322 --- /dev/null +++ b/src/3rdparty/symengine/symenginebegin.h @@ -0,0 +1,21 @@ +/* +Copyright libOpenCOR contributors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wdeprecated-literal-operator" +# pragma clang diagnostic ignored "-Wunused-parameter" +#endif diff --git a/src/3rdparty/symengine/symengineend.h b/src/3rdparty/symengine/symengineend.h new file mode 100644 index 0000000000..3d9678e222 --- /dev/null +++ b/src/3rdparty/symengine/symengineend.h @@ -0,0 +1,19 @@ +/* +Copyright libOpenCOR contributors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#ifdef __clang__ +# pragma clang diagnostic pop +#endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 466fb29304..afe5aa1b58 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -203,6 +203,13 @@ endif() apply_libxml2_settings(cellml) +target_link_libraries(cellml PRIVATE ${SYMENGINE_LIBRARIES}) +target_include_directories(cellml + PRIVATE + $ + ${SYMENGINE_INCLUDE_DIRS} +) + # Use target compile features to propagate features to consuming projects. target_compile_features(cellml PUBLIC cxx_std_17) diff --git a/src/analyser.cpp b/src/analyser.cpp index e79550d274..ad04541a5e 100644 --- a/src/analyser.cpp +++ b/src/analyser.cpp @@ -23,6 +23,10 @@ limitations under the License. #include #include +#include "symenginebegin.h" +#include +#include "symengineend.h" + #include "libcellml/analyserequation.h" #include "libcellml/analyserexternalvariable.h" #include "libcellml/generatorprofile.h" @@ -198,6 +202,133 @@ bool AnalyserInternalEquation::variableOnLhsOrRhs(const AnalyserInternalVariable || variableOnRhs(variable); } +SymEngineEquationResult AnalyserInternalEquation::symEngineEquation(const AnalyserEquationAstPtr &ast, const SymEngineSymbolMap &symbolMap) +{ + if (ast == nullptr) { + return {true, SymEngine::null}; + } + + AnalyserEquationAstPtr leftAst = ast->leftChild(); + AnalyserEquationAstPtr rightAst = ast->rightChild(); + + // Recursively call getConvertedAst on left and right children. + auto [leftSuccess, left] = symEngineEquation(leftAst, symbolMap); + auto [rightSuccess, right] = symEngineEquation(rightAst, symbolMap); + + if (!leftSuccess || !rightSuccess) { + return {false, SymEngine::null}; + } + + // Analyse mAst current type and value. + switch (ast->type()) { + case AnalyserEquationAst::Type::EQUALITY: + return {true, Eq(left, right)}; + case AnalyserEquationAst::Type::PLUS: + return {true, add(left, right)}; + case AnalyserEquationAst::Type::CI: + // Seems like the voi doesn't exist in mAllVariables, so we don't have an easy means of access. + if (symbolMap.find(ast->variable()->name()) == symbolMap.end()) { + return {false, SymEngine::null}; + } + return {true, symbolMap.at(ast->variable()->name())}; + default: + // Rearrangement is not possible with this type. + return {false, SymEngine::null}; + } +} + +AnalyserEquationAstPtr AnalyserInternalEquation::parseSymEngineExpression(const SymEngine::RCP &seExpression, + const AnalyserEquationAstPtr &parentAst, + const SymEngineVariableMap &variableMap) +{ + auto children = seExpression->get_args(); + + AnalyserEquationAstPtr ast = AnalyserEquationAst::create(); + + ast->setParent(parentAst); + + switch (seExpression->get_type_code()) { + case SymEngine::SYMENGINE_EQUALITY: { + ast->setType(AnalyserEquationAst::Type::EQUALITY); + break; + } + case SymEngine::SYMENGINE_ADD: { + ast->setType(AnalyserEquationAst::Type::PLUS); + break; + } + case SymEngine::SYMENGINE_MUL: { + ast->setType(AnalyserEquationAst::Type::TIMES); + break; + } + case SymEngine::SYMENGINE_SYMBOL: { + SymEngine::RCP symbolExpr = SymEngine::rcp_dynamic_cast(seExpression); + ast->setType(AnalyserEquationAst::Type::CI); + ast->setVariable(variableMap.at(symbolExpr)->mVariable); + break; + } + case SymEngine::SYMENGINE_INTEGER: { + ast->setType(AnalyserEquationAst::Type::CN); + ast->setValue(seExpression->__str__()); + break; + } + default: + break; + } + + // TODO Update to account for symengine expressions with 3 or more children. + if (children.size() > 0) { + ast->setLeftChild(parseSymEngineExpression(children[0], ast, variableMap)); + if (children.size() > 1) { + ast->setRightChild(parseSymEngineExpression(children[1], ast, variableMap)); + } + } + + return ast; +} + +AnalyserEquationAstPtr AnalyserInternalEquation::rearrangeFor(const AnalyserInternalVariablePtr &variable) +{ + SymEngineSymbolMap symbolMap; + SymEngineVariableMap variableMap; + + for (const auto &variable : mAllVariables) { + SymEngine::RCP symbol = SymEngine::symbol(variable->mVariable->name()); + symbolMap[variable->mVariable->name()] = symbol; + variableMap[symbol] = variable; + } + + auto [success, seEquation] = symEngineEquation(mAst, symbolMap); + if (!success) { + return nullptr; + } + + SymEngine::RCP solutionSet = solve(seEquation, symbolMap[variable->mVariable->name()]); + SymEngine::vec_basic solutions = solutionSet->get_args(); + + // Our system needs to be able to isolate a single solution. + if (solutions.size() != 1) { + return nullptr; + } + SymEngine::RCP answer = solutions.front(); + + // Rebuild the AST from the rearranged expression. + AnalyserEquationAstPtr ast = AnalyserEquationAst::create(); + AnalyserEquationAstPtr isolatedVariableAst = AnalyserEquationAst::create(); + AnalyserEquationAstPtr rearrangedEquationAst = parseSymEngineExpression(answer, nullptr, variableMap); + + ast->setType(AnalyserEquationAst::Type::EQUALITY); + ast->setLeftChild(isolatedVariableAst); + ast->setRightChild(rearrangedEquationAst); + + isolatedVariableAst->setType(AnalyserEquationAst::Type::CI); + isolatedVariableAst->setVariable(variable->mVariable); + isolatedVariableAst->setParent(ast); + + rearrangedEquationAst->setParent(ast); + + return ast; +} + bool AnalyserInternalEquation::check(const AnalyserModelPtr &analyserModel, bool checkNlaSystems) { // Nothing to check if the equation has a known type. @@ -278,6 +409,15 @@ bool AnalyserInternalEquation::check(const AnalyserModelPtr &analyserModel, bool mVariables.front() : nullptr; + // If we have one variable left, but it's not isolated, try to rearrange it. + if ((unknownVariableLeft != nullptr) && !variableOnLhsOrRhs(unknownVariableLeft)) { + auto newAst = rearrangeFor(unknownVariableLeft); + if (newAst != nullptr) { + // TODO Update variables and/or equation type when necessary. + mAst = newAst; + } + } + if (((unknownVariableLeft != nullptr) && (checkNlaSystems || variableOnLhsOrRhs(unknownVariableLeft))) || !initialisedVariables.empty()) { diff --git a/src/analyser_p.h b/src/analyser_p.h index f888861de4..733a5c121a 100644 --- a/src/analyser_p.h +++ b/src/analyser_p.h @@ -22,6 +22,12 @@ limitations under the License. #include "logger_p.h" #include "utilities.h" +namespace SymEngine { +template class RCP; +class Basic; +class Symbol; +} // namespace SymEngine + namespace libcellml { struct AnalyserInternalEquation; @@ -39,6 +45,10 @@ using AnalyserEquationPtrs = std::vector; using AnalyserVariablePtrs = std::vector; using AnalyserExternalVariablePtrs = std::vector; +using SymEngineVariableMap = std::map, AnalyserInternalVariablePtr, SymEngine::RCPBasicKeyLess>; +using SymEngineSymbolMap = std::map>; +using SymEngineEquationResult = std::tuple>; + struct AnalyserInternalVariable { enum struct Type @@ -128,6 +138,10 @@ struct AnalyserInternalEquation bool variableOnRhs(const AnalyserInternalVariablePtr &variable); bool variableOnLhsOrRhs(const AnalyserInternalVariablePtr &variable); + SymEngineEquationResult symEngineEquation(const AnalyserEquationAstPtr &ast, const SymEngineSymbolMap &symbolMap); + AnalyserEquationAstPtr parseSymEngineExpression(const SymEngine::RCP &seExpression, const AnalyserEquationAstPtr &parentAst, const SymEngineVariableMap &variableMap); + AnalyserEquationAstPtr rearrangeFor(const AnalyserInternalVariablePtr &variable); + bool check(const AnalyserModelPtr &analyserModel, bool checkNlaSystems); }; diff --git a/tests/analyser/analyser.cpp b/tests/analyser/analyser.cpp index ecc9db714b..add9e0f436 100644 --- a/tests/analyser/analyser.cpp +++ b/tests/analyser/analyser.cpp @@ -1060,3 +1060,17 @@ TEST(Analyser, unsuitablyConstrainedNlaSystem) EXPECT_EQ(libcellml::AnalyserModel::Type::UNSUITABLY_CONSTRAINED, analyser->analyserModel()->type()); } + +TEST(Analyser, rearrangeAlgebraicEquation) +{ + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("analyser/unarranged_algebraic_equation.cellml")); + + EXPECT_EQ(size_t(0), parser->issueCount()); + + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); + + EXPECT_EQ(libcellml::AnalyserModel::Type::ALGEBRAIC, analyser->analyserModel()->type()); +} diff --git a/tests/generator/generator.cpp b/tests/generator/generator.cpp index 411080c523..586a1bed7a 100644 --- a/tests/generator/generator.cpp +++ b/tests/generator/generator.cpp @@ -1602,30 +1602,6 @@ TEST(Generator, analyserModelScopeTest) EXPECT_EQ_FILE_CONTENTS("generator/hodgkin_huxley_squid_axon_model_1952/model.c", generator->implementationCode(analyserModel)); } -TEST(Generator, daeModel) -{ - auto parser = libcellml::Parser::create(false); - auto model = parser->parseModel(fileContents("generator/dae_cellml_1_1_model/model.cellml")); - - EXPECT_EQ(size_t(0), parser->errorCount()); - - auto analyser = libcellml::Analyser::create(); - - analyser->analyseModel(model); - - EXPECT_EQ(size_t(0), analyser->errorCount()); - - auto analyserModel = analyser->analyserModel(); - auto generator = libcellml::Generator::create(); - - EXPECT_EQ_FILE_CONTENTS("generator/dae_cellml_1_1_model/model.h", generator->interfaceCode(analyserModel)); - EXPECT_EQ_FILE_CONTENTS("generator/dae_cellml_1_1_model/model.c", generator->implementationCode(analyserModel)); - - auto profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); - - EXPECT_EQ_FILE_CONTENTS("generator/dae_cellml_1_1_model/model.py", generator->implementationCode(analyserModel, profile)); -} - TEST(Generator, variableInitialisedUsingAnotherVariable) { // Note: this should be in sync with the corresponding Analyser test. diff --git a/tests/resources/analyser/unarranged_algebraic_equation.cellml b/tests/resources/analyser/unarranged_algebraic_equation.cellml new file mode 100644 index 0000000000..5840ba82b5 --- /dev/null +++ b/tests/resources/analyser/unarranged_algebraic_equation.cellml @@ -0,0 +1,29 @@ + + + + + + + + + + x + 1 + + + + z + 3 + + + + x + + + y + z + + + + + diff --git a/tests/resources/generator/dae_cellml_1_1_model/model.c b/tests/resources/generator/dae_cellml_1_1_model/model.c deleted file mode 100644 index a5ebbb5eb3..0000000000 --- a/tests/resources/generator/dae_cellml_1_1_model/model.c +++ /dev/null @@ -1,190 +0,0 @@ -/* The content of this file was generated using the C profile of libCellML 0.6.3. */ - -#include "model.h" - -#include -#include - -const char VERSION[] = "0.7.0"; -const char LIBCELLML_VERSION[] = "0.6.3"; - -const size_t STATE_COUNT = 2; -const size_t CONSTANT_COUNT = 5; -const size_t COMPUTED_CONSTANT_COUNT = 0; -const size_t ALGEBRAIC_VARIABLE_COUNT = 5; - -const VariableInfo VOI_INFO = {"t", "second", "main"}; - -const VariableInfo STATE_INFO[] = { - {"q_1", "coulomb", "main"}, - {"v_3", "C_per_s", "main"} -}; - -const VariableInfo CONSTANT_INFO[] = { - {"v_in", "C_per_s", "main"}, - {"v_out", "C_per_s", "main"}, - {"C", "C2_per_J", "main"}, - {"R", "Js_per_C2", "main"}, - {"L", "Js2_per_C2", "main"} -}; - -const VariableInfo COMPUTED_CONSTANT_INFO[] = { -}; - -const VariableInfo ALGEBRAIC_INFO[] = { - {"v_1", "C_per_s", "main"}, - {"v_2", "C_per_s", "main"}, - {"u_3", "J_per_C", "main"}, - {"u_2", "J_per_C", "main"}, - {"u_1", "J_per_C", "main"} -}; - -double * createStatesArray() -{ - double *res = (double *) malloc(STATE_COUNT*sizeof(double)); - - for (size_t i = 0; i < STATE_COUNT; ++i) { - res[i] = NAN; - } - - return res; -} - -double * createConstantsArray() -{ - double *res = (double *) malloc(CONSTANT_COUNT*sizeof(double)); - - for (size_t i = 0; i < CONSTANT_COUNT; ++i) { - res[i] = NAN; - } - - return res; -} - -double * createComputedConstantsArray() -{ - double *res = (double *) malloc(COMPUTED_CONSTANT_COUNT*sizeof(double)); - - for (size_t i = 0; i < COMPUTED_CONSTANT_COUNT; ++i) { - res[i] = NAN; - } - - return res; -} - -double * createAlgebraicVariablesArray() -{ - double *res = (double *) malloc(ALGEBRAIC_VARIABLE_COUNT*sizeof(double)); - - for (size_t i = 0; i < ALGEBRAIC_VARIABLE_COUNT; ++i) { - res[i] = NAN; - } - - return res; -} - -void deleteArray(double *array) -{ - free(array); -} - -typedef struct { - double voi; - double *states; - double *rates; - double *constants; - double *computedConstants; - double *algebraicVariables; -} RootFindingInfo; - -extern void nlaSolve(void (*objectiveFunction)(double *, double *, void *), - double *u, size_t n, void *data); - -void objectiveFunction0(double *u, double *f, void *data) -{ - double voi = ((RootFindingInfo *) data)->voi; - double *states = ((RootFindingInfo *) data)->states; - double *rates = ((RootFindingInfo *) data)->rates; - double *constants = ((RootFindingInfo *) data)->constants; - double *computedConstants = ((RootFindingInfo *) data)->computedConstants; - double *algebraicVariables = ((RootFindingInfo *) data)->algebraicVariables; - - algebraicVariables[0] = u[0]; - - f[0] = constants[0]-(algebraicVariables[0]+algebraicVariables[1]); -} - -void findRoot0(double voi, double *states, double *rates, double *constants, double *computedConstants, double *algebraicVariables) -{ - RootFindingInfo rfi = { voi, states, rates, constants, computedConstants, algebraicVariables }; - double u[1]; - - u[0] = algebraicVariables[0]; - - nlaSolve(objectiveFunction0, u, 1, &rfi); - - algebraicVariables[0] = u[0]; -} - -void objectiveFunction1(double *u, double *f, void *data) -{ - double voi = ((RootFindingInfo *) data)->voi; - double *states = ((RootFindingInfo *) data)->states; - double *rates = ((RootFindingInfo *) data)->rates; - double *constants = ((RootFindingInfo *) data)->constants; - double *computedConstants = ((RootFindingInfo *) data)->computedConstants; - double *algebraicVariables = ((RootFindingInfo *) data)->algebraicVariables; - - algebraicVariables[2] = u[0]; - - f[0] = algebraicVariables[4]-(algebraicVariables[3]+algebraicVariables[2]); -} - -void findRoot1(double voi, double *states, double *rates, double *constants, double *computedConstants, double *algebraicVariables) -{ - RootFindingInfo rfi = { voi, states, rates, constants, computedConstants, algebraicVariables }; - double u[1]; - - u[0] = algebraicVariables[2]; - - nlaSolve(objectiveFunction1, u, 1, &rfi); - - algebraicVariables[2] = u[0]; -} - -void initialiseArrays(double *states, double *rates, double *constants, double *computedConstants, double *algebraicVariables) -{ - states[0] = 1.0; - states[1] = 0.0; - constants[0] = 1.0; - constants[1] = 1.0; - constants[2] = 20.0; - constants[3] = 2.0; - constants[4] = 10.0; - algebraicVariables[0] = 0.0; - algebraicVariables[2] = 0.0; -} - -void computeComputedConstants(double *states, double *rates, double *constants, double *computedConstants, double *algebraic) -{ -} - -void computeRates(double voi, double *states, double *rates, double *constants, double *computedConstants, double *algebraicVariables) -{ - algebraicVariables[1] = states[1]+constants[1]; - findRoot0(voi, states, rates, constants, computedConstants, algebraicVariables); - rates[0] = algebraicVariables[0]; - algebraicVariables[3] = constants[3]*algebraicVariables[1]; - algebraicVariables[4] = states[0]/constants[2]; - findRoot1(voi, states, rates, constants, computedConstants, algebraicVariables); - rates[1] = algebraicVariables[2]/constants[4]; -} - -void computeVariables(double voi, double *states, double *rates, double *constants, double *computedConstants, double *algebraicVariables) -{ - algebraicVariables[1] = states[1]+constants[1]; - findRoot0(voi, states, rates, constants, computedConstants, algebraicVariables); - algebraicVariables[3] = constants[3]*algebraicVariables[1]; - algebraicVariables[4] = states[0]/constants[2]; - findRoot1(voi, states, rates, constants, computedConstants, algebraicVariables); -} diff --git a/tests/resources/generator/dae_cellml_1_1_model/model.cellml b/tests/resources/generator/dae_cellml_1_1_model/model.cellml deleted file mode 100644 index 3cf3994279..0000000000 --- a/tests/resources/generator/dae_cellml_1_1_model/model.cellml +++ /dev/null @@ -1,127 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - t - - q_1 - - v_1 - - - - v_in - - - v_1 - v_2 - - - - - v_2 - - - v_3 - v_out - - - - - u_1 - - - u_2 - u_3 - - - - - - u_1 - - - q_1 - C - - - - - u_2 - - - R - v_2 - - - - - - - - t - - v_3 - - - - u_3 - L - - - - - diff --git a/tests/resources/generator/dae_cellml_1_1_model/model.h b/tests/resources/generator/dae_cellml_1_1_model/model.h deleted file mode 100644 index 3350366aef..0000000000 --- a/tests/resources/generator/dae_cellml_1_1_model/model.h +++ /dev/null @@ -1,37 +0,0 @@ -/* The content of this file was generated using the C profile of libCellML 0.6.3. */ - -#pragma once - -#include - -extern const char VERSION[]; -extern const char LIBCELLML_VERSION[]; - -extern const size_t STATE_COUNT; -extern const size_t CONSTANT_COUNT; -extern const size_t COMPUTED_CONSTANT_COUNT; -extern const size_t ALGEBRAIC_VARIABLE_COUNT; - -typedef struct { - char name[6]; - char units[11]; - char component[5]; -} VariableInfo; - -extern const VariableInfo VOI_INFO; -extern const VariableInfo STATE_INFO[]; -extern const VariableInfo CONSTANT_INFO[]; -extern const VariableInfo COMPUTED_CONSTANT_INFO[]; -extern const VariableInfo ALGEBRAIC_INFO[]; - -double * createStatesArray(); -double * createConstantsArray(); -double * createComputedConstantsArray(); -double * createAlgebraicVariablesArray(); - -void deleteArray(double *array); - -void initialiseArrays(double *states, double *rates, double *constants, double *computedConstants, double *algebraicVariables); -void computeComputedConstants(double *states, double *rates, double *constants, double *computedConstants, double *algebraic); -void computeRates(double voi, double *states, double *rates, double *constants, double *computedConstants, double *algebraicVariables); -void computeVariables(double voi, double *states, double *rates, double *constants, double *computedConstants, double *algebraicVariables); diff --git a/tests/resources/generator/dae_cellml_1_1_model/model.py b/tests/resources/generator/dae_cellml_1_1_model/model.py deleted file mode 100644 index e847325529..0000000000 --- a/tests/resources/generator/dae_cellml_1_1_model/model.py +++ /dev/null @@ -1,138 +0,0 @@ -# The content of this file was generated using the Python profile of libCellML 0.6.3. - -from enum import Enum -from math import * - - -__version__ = "0.6.0" -LIBCELLML_VERSION = "0.6.3" - -STATE_COUNT = 2 -CONSTANT_COUNT = 5 -COMPUTED_CONSTANT_COUNT = 0 -ALGEBRAIC_VARIABLE_COUNT = 5 - -VOI_INFO = {"name": "t", "units": "second", "component": "main"} - -STATE_INFO = [ - {"name": "q_1", "units": "coulomb", "component": "main"}, - {"name": "v_3", "units": "C_per_s", "component": "main"} -] - -CONSTANT_INFO = [ - {"name": "v_in", "units": "C_per_s", "component": "main"}, - {"name": "v_out", "units": "C_per_s", "component": "main"}, - {"name": "C", "units": "C2_per_J", "component": "main"}, - {"name": "R", "units": "Js_per_C2", "component": "main"}, - {"name": "L", "units": "Js2_per_C2", "component": "main"} -] - -COMPUTED_CONSTANT_INFO = [ -] - -ALGEBRAIC_INFO = [ - {"name": "v_1", "units": "C_per_s", "component": "main"}, - {"name": "v_2", "units": "C_per_s", "component": "main"}, - {"name": "u_3", "units": "J_per_C", "component": "main"}, - {"name": "u_2", "units": "J_per_C", "component": "main"}, - {"name": "u_1", "units": "J_per_C", "component": "main"} -] - - -def create_states_array(): - return [nan]*STATE_COUNT - - -def create_constants_array(): - return [nan]*CONSTANT_COUNT - - -def create_computed_constants_array(): - return [nan]*COMPUTED_CONSTANT_COUNT - - -def create_algebraic_variables_array(): - return [nan]*ALGEBRAIC_VARIABLE_COUNT - - -from nlasolver import nla_solve - - -def objective_function_0(u, f, data): - voi = data[0] - states = data[1] - rates = data[2] - constants = data[3] - computed_constants = data[4] - algebraic_variables = data[5] - - algebraicVariables[0] = u[0] - - f[0] = constants[0]-(algebraicVariables[0]+algebraicVariables[1]) - - -def find_root_0(voi, states, rates, constants, computed_constants, algebraic_variables): - u = [nan]*1 - - u[0] = algebraicVariables[0] - - u = nla_solve(objective_function_0, u, 1, [voi, states, rates, constants, computed_constants, algebraic_variables]) - - algebraicVariables[0] = u[0] - - -def objective_function_1(u, f, data): - voi = data[0] - states = data[1] - rates = data[2] - constants = data[3] - computed_constants = data[4] - algebraic_variables = data[5] - - algebraicVariables[2] = u[0] - - f[0] = algebraicVariables[4]-(algebraicVariables[3]+algebraicVariables[2]) - - -def find_root_1(voi, states, rates, constants, computed_constants, algebraic_variables): - u = [nan]*1 - - u[0] = algebraicVariables[2] - - u = nla_solve(objective_function_1, u, 1, [voi, states, rates, constants, computed_constants, algebraic_variables]) - - algebraicVariables[2] = u[0] - - -def initialise_arrays(states, rates, constants, computed_constants, algebraic_variables): - states[0] = 1.0 - states[1] = 0.0 - constants[0] = 1.0 - constants[1] = 1.0 - constants[2] = 20.0 - constants[3] = 2.0 - constants[4] = 10.0 - algebraicVariables[0] = 0.0 - algebraicVariables[2] = 0.0 - - -def compute_computed_constants(states, rates, constants, computed_constants, algebraic): - pass - - -def compute_rates(voi, states, rates, constants, computed_constants, algebraic_variables): - algebraicVariables[1] = states[1]+constants[1] - find_root_0(voi, states, rates, constants, computed_constants, algebraic_variables) - rates[0] = algebraicVariables[0] - algebraicVariables[3] = constants[3]*algebraicVariables[1] - algebraicVariables[4] = states[0]/constants[2] - find_root_1(voi, states, rates, constants, computed_constants, algebraic_variables) - rates[1] = algebraicVariables[2]/constants[4] - - -def compute_variables(voi, states, rates, constants, computed_constants, algebraic_variables): - algebraicVariables[1] = states[1]+constants[1] - find_root_0(voi, states, rates, constants, computed_constants, algebraic_variables) - algebraicVariables[3] = constants[3]*algebraicVariables[1] - algebraicVariables[4] = states[0]/constants[2] - find_root_1(voi, states, rates, constants, computed_constants, algebraic_variables)