From b2748c5b5cf70eac7fdcd0ae2924339d62475356 Mon Sep 17 00:00:00 2001 From: Alan Garny Date: Sun, 27 Oct 2024 20:02:42 +1300 Subject: [PATCH] Generator: take into account tracked/untracked variables when generating some code. --- src/api/libcellml/analyser.h | 5 +- src/generator.cpp | 63 ++- src/generator_p.h | 3 +- tests/coverage/coverage.cpp | 17 + tests/generator/generatortrackedvariables.cpp | 140 +++++- .../coverage/generator/model.no.tracking.c | 427 ++++++++++++++++++ .../coverage/generator/model.no.tracking.h | 37 ++ .../model.untracked.algebraic.variables.c | 131 ++++++ ... => model.untracked.algebraic.variables.h} | 0 .../model.untracked.algebraic.variables.py | 106 +++++ .../model.untracked.computed.constants.c | 150 ++++++ .../model.untracked.computed.constants.h | 37 ++ .../model.untracked.computed.constants.py | 125 +++++ .../model.untracked.constants.c | 148 ++++++ .../model.untracked.constants.h | 37 ++ .../model.untracked.constants.py | 122 +++++ ...tracking.c => model.untracked.variables.c} | 2 +- .../model.untracked.variables.h | 37 ++ ...acking.py => model.untracked.variables.py} | 0 ...model.untracked.variables.with.externals.c | 124 +++++ ...model.untracked.variables.with.externals.h | 42 ++ ...odel.untracked.variables.with.externals.py | 93 ++++ 22 files changed, 1810 insertions(+), 36 deletions(-) create mode 100644 tests/resources/coverage/generator/model.no.tracking.c create mode 100644 tests/resources/coverage/generator/model.no.tracking.h create mode 100644 tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.algebraic.variables.c rename tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/{model.no.tracking.h => model.untracked.algebraic.variables.h} (100%) create mode 100644 tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.algebraic.variables.py create mode 100644 tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.computed.constants.c create mode 100644 tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.computed.constants.h create mode 100644 tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.computed.constants.py create mode 100644 tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.constants.c create mode 100644 tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.constants.h create mode 100644 tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.constants.py rename tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/{model.no.tracking.c => model.untracked.variables.c} (98%) create mode 100644 tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.variables.h rename tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/{model.no.tracking.py => model.untracked.variables.py} (100%) create mode 100644 tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.variables.with.externals.c create mode 100644 tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.variables.with.externals.h create mode 100644 tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.variables.with.externals.py diff --git a/src/api/libcellml/analyser.h b/src/api/libcellml/analyser.h index eff53741e4..570d0808e2 100644 --- a/src/api/libcellml/analyser.h +++ b/src/api/libcellml/analyser.h @@ -62,7 +62,8 @@ class LIBCELLML_EXPORT Analyser: public Logger * @brief Add a @ref VariablePtr as an external variable to this @ref Analyser. * * Add the given @ref VariablePtr as an external variable to this @ref Analyser, but only if it has not already been - * added. + * added. Please note that it is your responsibility to ensure that all the variables on which an external variable + * depends are tracked. * * @param variable The @ref Variable to add as an external variable. * @@ -76,6 +77,8 @@ class LIBCELLML_EXPORT Analyser: public Logger * @brief Add an @ref AnalyserExternalVariable to this @ref Analyser. * * Add the given @ref AnalyserExternalVariable to this @ref Analyser, but only if it has not already been added. + * Please note that it is your responsibility to ensure that all the variables on which an external variable depends + * are tracked. * * @param externalVariable The @ref AnalyserExternalVariable to add. * diff --git a/src/generator.cpp b/src/generator.cpp index 8d143c6645..dbe0d8467c 100644 --- a/src/generator.cpp +++ b/src/generator.cpp @@ -1853,16 +1853,23 @@ std::string Generator::GeneratorImpl::generateCode(const AnalyserModelPtr &model code = generateCode(model, ast->leftChild()); break; - case AnalyserEquationAst::Type::CI: + case AnalyserEquationAst::Type::CI: { code = generateVariableNameCode(model, ast->variable(), ast->parent()->type() != AnalyserEquationAst::Type::DIFF); + auto astParent = ast->parent(); + if ((model != nullptr) - && (ast->parent()->type() == AnalyserEquationAst::Type::EQUALITY) + && (astParent->type() == AnalyserEquationAst::Type::EQUALITY) + && (astParent->leftChild() == ast) && isUntrackedVariable(model->variable(ast->variable()))) { + // Note: we want this AST to be its parent's left child since a declaration is always of the form x = RHS, + // not LHS = x. + code = replace(mProfile->variableDeclarationString(), "[CODE]", code); } + } - break; + break; case AnalyserEquationAst::Type::CN: code = generateDoubleCode(ast->value()); @@ -2012,11 +2019,13 @@ std::string Generator::GeneratorImpl::generateEquationCode(const AnalyserModelPt if (!isSomeConstant(equation, includeComputedConstants)) { for (const auto &dependency : equation->dependencies()) { - if ((dependency->type() != AnalyserEquation::Type::ODE) - && !isSomeConstant(dependency, includeComputedConstants) - && (equationsForDependencies.empty() - || isToBeComputedAgain(dependency) - || (std::find(equationsForDependencies.begin(), equationsForDependencies.end(), dependency) != equationsForDependencies.end()))) { + if (((dependency->type() == AnalyserEquation::Type::COMPUTED_CONSTANT) + && isUntrackedVariable(dependency->computedConstants().front())) + || ((dependency->type() != AnalyserEquation::Type::ODE) + && !isSomeConstant(dependency, includeComputedConstants) + && (equationsForDependencies.empty() + || isToBeComputedAgain(dependency) + || (std::find(equationsForDependencies.begin(), equationsForDependencies.end(), dependency) != equationsForDependencies.end())))) { res += generateEquationCode(model, dependency, remainingEquations, equationsForDependencies, generatedConstantDependencies, includeComputedConstants); } @@ -2028,12 +2037,16 @@ std::string Generator::GeneratorImpl::generateEquationCode(const AnalyserModelPt switch (equation->type()) { case AnalyserEquation::Type::EXTERNAL: for (const auto &variable : variables(equation)) { + auto code = generateVariableNameCode(model, variable->variable()) + + mProfile->equalityString() + + replace(mProfile->externalVariableMethodCallString(modelHasOdes(model)), + "[INDEX]", convertToString(variable->index())) + + mProfile->commandSeparatorString() + "\n"; + + code = replace(mProfile->variableDeclarationString(), "[CODE]", code); + res += mProfile->indentString() - + generateVariableNameCode(model, variable->variable()) - + mProfile->equalityString() - + replace(mProfile->externalVariableMethodCallString(modelHasOdes(model)), - "[INDEX]", convertToString(variable->index())) - + mProfile->commandSeparatorString() + "\n"; + + code; } break; @@ -2057,10 +2070,10 @@ std::string Generator::GeneratorImpl::generateEquationCode(const AnalyserModelPt std::string Generator::GeneratorImpl::generateEquationCode(const AnalyserModelPtr &model, const AnalyserEquationPtr &equation, - std::vector &remainingEquations) + std::vector &remainingEquations, + std::vector &generatedConstantDependencies) { std::vector dummyEquationsForComputeVariables; - std::vector generatedConstantDependencies; return generateEquationCode(model, equation, remainingEquations, dummyEquationsForComputeVariables, generatedConstantDependencies, true); @@ -2173,11 +2186,11 @@ void Generator::GeneratorImpl::addImplementationInitialiseVariablesMethodCode(co // Initialise our computed constants that are initialised using an equation (e.g., x = 3 rather than x with an // initial value of 3). - auto equations = model->equations(); + std::vector generatedConstantDependencies; - for (const auto &equation : equations) { + for (const auto &equation : model->equations()) { if (equation->type() == AnalyserEquation::Type::CONSTANT) { - methodBody += generateEquationCode(model, equation, remainingEquations); + methodBody += generateEquationCode(model, equation, remainingEquations, generatedConstantDependencies); } } @@ -2207,11 +2220,12 @@ void Generator::GeneratorImpl::addImplementationComputeComputedConstantsMethodCo { if (!mProfile->implementationComputeComputedConstantsMethodString().empty()) { std::string methodBody; + std::vector generatedConstantDependencies; for (const auto &equation : model->equations()) { if ((equation->type() == AnalyserEquation::Type::COMPUTED_CONSTANT) && isTrackedVariable(equation->computedConstants().front())) { - methodBody += generateEquationCode(model, equation, remainingEquations); + methodBody += generateEquationCode(model, equation, remainingEquations, generatedConstantDependencies); } } @@ -2229,6 +2243,7 @@ void Generator::GeneratorImpl::addImplementationComputeRatesMethodCode(const Ana if (modelHasOdes(model) && !implementationComputeRatesMethodString.empty()) { std::string methodBody; + std::vector generatedConstantDependencies; for (const auto &equation : model->equations()) { // A rate is computed either through an ODE equation or through an @@ -2241,7 +2256,7 @@ void Generator::GeneratorImpl::addImplementationComputeRatesMethodCode(const Ana || ((equation->type() == AnalyserEquation::Type::NLA) && (variables.size() == 1) && (variables[0]->type() == AnalyserVariable::Type::STATE))) { - methodBody += generateEquationCode(model, equation, remainingEquations); + methodBody += generateEquationCode(model, equation, remainingEquations, generatedConstantDependencies); } } @@ -2264,8 +2279,12 @@ void Generator::GeneratorImpl::addImplementationComputeVariablesMethodCode(const std::vector generatedConstantDependencies; for (const auto &equation : equations) { - if ((std::find(remainingEquations.begin(), remainingEquations.end(), equation) != remainingEquations.end()) - || isToBeComputedAgain(equation)) { + if (((std::find(remainingEquations.begin(), remainingEquations.end(), equation) != remainingEquations.end()) + || isToBeComputedAgain(equation)) + && (((equation->type() == AnalyserEquation::Type::ALGEBRAIC) + && isTrackedVariable(equation->algebraic().front())) + || ((equation->type() == AnalyserEquation::Type::EXTERNAL) + && isTrackedVariable(equation->externals().front())))) { methodBody += generateEquationCode(model, equation, newRemainingEquations, remainingEquations, generatedConstantDependencies, false); } diff --git a/src/generator_p.h b/src/generator_p.h index fa85f8a2b6..0ac34cdf24 100644 --- a/src/generator_p.h +++ b/src/generator_p.h @@ -182,7 +182,8 @@ struct Generator::GeneratorImpl std::vector &generatedConstantDependencies, bool includeComputedConstants); std::string generateEquationCode(const AnalyserModelPtr &model, const AnalyserEquationPtr &equation, - std::vector &remainingEquations); + std::vector &remainingEquations, + std::vector &generatedConstantDependencies); void addInterfaceComputeModelMethodsCode(const AnalyserModelPtr &model); std::string generateConstantInitialisationCode(const AnalyserModelPtr &model, diff --git a/tests/coverage/coverage.cpp b/tests/coverage/coverage.cpp index e2cd5e710b..ec9e1aa480 100644 --- a/tests/coverage/coverage.cpp +++ b/tests/coverage/coverage.cpp @@ -969,6 +969,23 @@ TEST(Coverage, generator) libcellml::Generator::equationCode(analyser->model()->equation(0)->ast()); } +TEST(Coverage, generatorWithNoTracking) +{ + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("coverage/generator/model.cellml")); + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); + + auto analyserModel = analyser->model(); + auto generator = libcellml::Generator::create(); + + generator->untrackAllVariables(analyserModel); + + EXPECT_EQ_FILE_CONTENTS("coverage/generator/model.no.tracking.h", generator->interfaceCode(analyserModel)); + EXPECT_EQ_FILE_CONTENTS("coverage/generator/model.no.tracking.c", generator->implementationCode(analyserModel)); +} + TEST(CoverageValidator, degreeElementWithOneSibling) { const std::string math = diff --git a/tests/generator/generatortrackedvariables.cpp b/tests/generator/generatortrackedvariables.cpp index 3aba9ab6a8..348e451587 100644 --- a/tests/generator/generatortrackedvariables.cpp +++ b/tests/generator/generatortrackedvariables.cpp @@ -439,7 +439,7 @@ TEST(GeneratorTrackedVariables, trackAndUntrackAllVariables) EXPECT_EQ(size_t(0), generator->untrackedVariableCount(analyserModel)); } -TEST(GeneratorTrackedVariables, hodgkinHuxleySquidAxonModel1952NoTracking) +TEST(GeneratorTrackedVariables, hodgkinHuxleySquidAxonModel1952UntrackedVariables) { auto parser = libcellml::Parser::create(); auto model = parser->parseModel(fileContents("generator/hodgkin_huxley_squid_axon_model_1952/model.cellml")); @@ -452,24 +452,142 @@ TEST(GeneratorTrackedVariables, hodgkinHuxleySquidAxonModel1952NoTracking) generator->untrackAllVariables(analyserModel); - EXPECT_EQ_FILE_CONTENTS("generator/hodgkin_huxley_squid_axon_model_1952/model.no.tracking.h", generator->interfaceCode(analyserModel)); - EXPECT_EQ_FILE_CONTENTS("generator/hodgkin_huxley_squid_axon_model_1952/model.no.tracking.c", generator->implementationCode(analyserModel)); + auto profile = generator->profile(); - auto profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); + profile->setInterfaceFileNameString("model.untracked.variables.h"); + + EXPECT_EQ_FILE_CONTENTS("generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.variables.h", generator->interfaceCode(analyserModel)); + EXPECT_EQ_FILE_CONTENTS("generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.variables.c", generator->implementationCode(analyserModel)); + + profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); + + generator->setProfile(profile); + + EXPECT_EQ_FILE_CONTENTS("generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.variables.py", generator->implementationCode(analyserModel)); + + // With some external variables. + + auto potassium_channel_n_gate_alpha_n = model->component("potassium_channel_n_gate")->variable("alpha_n"); + auto external_sodium_channel_i_Na = libcellml::AnalyserExternalVariable::create(model->component("sodium_channel")->variable("i_Na")); + + external_sodium_channel_i_Na->addDependency(potassium_channel_n_gate_alpha_n); + external_sodium_channel_i_Na->addDependency(model->component("sodium_channel_h_gate")->variable("h")); + + analyser->addExternalVariable(libcellml::AnalyserExternalVariable::create(model->component("membrane")->variable("V"))); + analyser->addExternalVariable(external_sodium_channel_i_Na); + analyser->addExternalVariable(libcellml::AnalyserExternalVariable::create(potassium_channel_n_gate_alpha_n)); + + analyser->analyseModel(model); + + analyserModel = analyser->model(); + + generator->untrackAllVariables(analyserModel); + + profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::C); + + generator->setProfile(profile); + + profile->setInterfaceFileNameString("model.untracked.variables.with.externals.h"); + + EXPECT_EQ_FILE_CONTENTS("generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.variables.with.externals.h", generator->interfaceCode(analyserModel)); + EXPECT_EQ_FILE_CONTENTS("generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.variables.with.externals.c", generator->implementationCode(analyserModel)); + + profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); + + generator->setProfile(profile); + + EXPECT_EQ_FILE_CONTENTS("generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.variables.with.externals.py", generator->implementationCode(analyserModel)); +} + +TEST(GeneratorTrackedVariables, hodgkinHuxleySquidAxonModel1952UntrackedConstants) +{ + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/hodgkin_huxley_squid_axon_model_1952/model.cellml")); + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); + + auto analyserModel = analyser->model(); + auto generator = libcellml::Generator::create(); + + generator->untrackAllConstants(analyserModel); + + auto profile = generator->profile(); + + profile->setInterfaceFileNameString("model.untracked.constants.h"); + + EXPECT_EQ_FILE_CONTENTS("generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.constants.h", generator->interfaceCode(analyserModel)); + EXPECT_EQ_FILE_CONTENTS("generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.constants.c", generator->implementationCode(analyserModel)); + + profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); + + generator->setProfile(profile); + + EXPECT_EQ_FILE_CONTENTS("generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.constants.py", generator->implementationCode(analyserModel)); +} + +TEST(GeneratorTrackedVariables, hodgkinHuxleySquidAxonModel1952UntrackedComputedConstants) +{ + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/hodgkin_huxley_squid_axon_model_1952/model.cellml")); + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); + + auto analyserModel = analyser->model(); + auto generator = libcellml::Generator::create(); + + generator->untrackAllComputedConstants(analyserModel); + + auto profile = generator->profile(); + + profile->setInterfaceFileNameString("model.untracked.computed.constants.h"); + + EXPECT_EQ_FILE_CONTENTS("generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.computed.constants.h", generator->interfaceCode(analyserModel)); + EXPECT_EQ_FILE_CONTENTS("generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.computed.constants.c", generator->implementationCode(analyserModel)); + + profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); + + generator->setProfile(profile); + + EXPECT_EQ_FILE_CONTENTS("generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.computed.constants.py", generator->implementationCode(analyserModel)); +} + +TEST(GeneratorTrackedVariables, hodgkinHuxleySquidAxonModel1952UntrackedAlgebraicVariables) +{ + auto parser = libcellml::Parser::create(); + auto model = parser->parseModel(fileContents("generator/hodgkin_huxley_squid_axon_model_1952/model.cellml")); + auto analyser = libcellml::Analyser::create(); + + analyser->analyseModel(model); + + auto analyserModel = analyser->model(); + auto generator = libcellml::Generator::create(); + + generator->untrackAllAlgebraic(analyserModel); + + auto profile = generator->profile(); + + profile->setInterfaceFileNameString("model.untracked.algebraic.variables.h"); + + EXPECT_EQ_FILE_CONTENTS("generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.algebraic.variables.h", generator->interfaceCode(analyserModel)); + EXPECT_EQ_FILE_CONTENTS("generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.algebraic.variables.c", generator->implementationCode(analyserModel)); + + profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); generator->setProfile(profile); - EXPECT_EQ_FILE_CONTENTS("generator/hodgkin_huxley_squid_axon_model_1952/model.no.tracking.py", generator->implementationCode(analyserModel)); + EXPECT_EQ_FILE_CONTENTS("generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.algebraic.variables.py", generator->implementationCode(analyserModel)); } /** * Need the following tests: - * - ODE HH52 + No tracking - * - ODE HH52 + No tracking + Externals (with some dependencies on untracked variables) - * - ODE HH52 + Some tracking (with some dependencies on untracked variables) - * - ODE HH52 + Some tracking (with some dependencies on untracked variables) + Externals (with some dependencies on untracked variables) + * - ODE HH52 + No tracking -- DONE + * - ODE HH52 + No tracking + Externals -- DONE + * - ODE HH52 + Some tracking (with some dependencies on untracked variables) -- DONE + * - ODE HH52 + Some tracking (with some dependencies on untracked variables) + Externals * - DAE HH52 + No tracking - * - DAE HH52 + No tracking + Externals (with some dependencies on untracked variables) + * - DAE HH52 + No tracking + Externals * - DAE HH52 + Some tracking (with some dependencies on untracked variables) - * - DAE HH52 + Some tracking (with some dependencies on untracked variables) + Externals (with some dependencies on untracked variables) + * - DAE HH52 + Some tracking (with some dependencies on untracked variables) + Externals */ diff --git a/tests/resources/coverage/generator/model.no.tracking.c b/tests/resources/coverage/generator/model.no.tracking.c new file mode 100644 index 0000000000..91da9d504e --- /dev/null +++ b/tests/resources/coverage/generator/model.no.tracking.c @@ -0,0 +1,427 @@ +/* The content of this file was generated using the C profile of libCellML 0.6.0. */ + +#include "model.h" + +#include +#include + +const char VERSION[] = "0.6.0"; +const char LIBCELLML_VERSION[] = "0.6.0"; + +const size_t STATE_COUNT = 1; +const size_t CONSTANT_COUNT = 0; +const size_t COMPUTED_CONSTANT_COUNT = 0; +const size_t ALGEBRAIC_COUNT = 0; + +const VariableInfo VOI_INFO = {"t", "second", "my_component"}; + +const VariableInfo STATE_INFO[] = { + {"x", "dimensionless", "my_component"} +}; + +const VariableInfo CONSTANT_INFO[] = { +}; + +const VariableInfo COMPUTED_CONSTANT_INFO[] = { +}; + +const VariableInfo ALGEBRAIC_INFO[] = { +}; + +double xor(double x, double y) +{ + return (x != 0.0) ^ (y != 0.0); +} + +double min(double x, double y) +{ + return (x < y)?x:y; +} + +double max(double x, double y) +{ + return (x > y)?x:y; +} + +double sec(double x) +{ + return 1.0/cos(x); +} + +double csc(double x) +{ + return 1.0/sin(x); +} + +double cot(double x) +{ + return 1.0/tan(x); +} + +double sech(double x) +{ + return 1.0/cosh(x); +} + +double csch(double x) +{ + return 1.0/sinh(x); +} + +double coth(double x) +{ + return 1.0/tanh(x); +} + +double asec(double x) +{ + return acos(1.0/x); +} + +double acsc(double x) +{ + return asin(1.0/x); +} + +double acot(double x) +{ + return atan(1.0/x); +} + +double asech(double x) +{ + double oneOverX = 1.0/x; + + return log(oneOverX+sqrt(oneOverX*oneOverX-1.0)); +} + +double acsch(double x) +{ + double oneOverX = 1.0/x; + + return log(oneOverX+sqrt(oneOverX*oneOverX+1.0)); +} + +double acoth(double x) +{ + double oneOverX = 1.0/x; + + return 0.5*log((1.0+oneOverX)/(1.0-oneOverX)); +} + +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 * createAlgebraicArray() +{ + double *res = (double *) malloc(ALGEBRAIC_COUNT*sizeof(double)); + + for (size_t i = 0; i < ALGEBRAIC_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 *algebraic; +} 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 *algebraic = ((RootFindingInfo *) data)->algebraic; + + algebraic[0] = u[0]; + algebraic[1] = u[1]; + + f[0] = my_component_eqnNlaVariable1+my_component_eqnNlaVariable2+states[0]-0.0; + f[1] = my_component_eqnNlaVariable1-my_component_eqnNlaVariable2-(my_component_eqnComputedConstant1+my_component_eqnComputedConstant2); +} + +void findRoot0(double voi, double *states, double *rates, double *constants, double *computedConstants, double *algebraic) +{ + RootFindingInfo rfi = { voi, states, rates, constants, computedConstants, algebraic }; + double u[2]; + + u[0] = algebraic[0]; + u[1] = algebraic[1]; + + nlaSolve(objectiveFunction0, u, 2, &rfi); + + algebraic[0] = u[0]; + algebraic[1] = u[1]; +} + +void initialiseVariables(double *states, double *rates, double *constants, double *computedConstants, double *algebraic) +{ + states[0] = 0.0; + double my_component_eqnCnInteger = 123.0; + double my_component_eqnCnDouble = 123.456789; + double my_component_eqnCnIntegerWithExponent = 123.0e99; + double my_component_eqnCnDoubleWithExponent = 123.456789e99; + double my_component_eqnTrue = 1.0; + double my_component_eqnFalse = 0.0; + double my_component_eqnExponentiale = 2.71828182845905; + double my_component_eqnPi = 3.14159265358979; + double my_component_eqnInfinity = INFINITY; + double my_component_eqnNotanumber = NAN; + double my_component_eqnComputedConstant1 = 1.0; + double my_component_eqnComputedConstant2 = 3.0; +} + +void computeComputedConstants(double *constants, double *computedConstants) +{ +} + +void computeRates(double voi, double *states, double *rates, double *constants, double *computedConstants, double *algebraic) +{ + rates[0] = 1.0; +} + +void computeVariables(double voi, double *states, double *rates, double *constants, double *computedConstants, double *algebraic) +{ + double my_component_m = 1.0; + double my_component_n = 2.0; + double my_component_eqnEq = my_component_m == my_component_n; + double my_component_eqnEqCoverageParentheses = my_component_m/(my_component_n == my_component_n); + double my_component_eqnNeq = my_component_m != my_component_n; + double my_component_o = 3.0; + double my_component_eqnNeqCoverageParentheses = my_component_m/(my_component_n != my_component_o); + double my_component_eqnLt = my_component_m < my_component_n; + double my_component_eqnLtCoverageParentheses = my_component_m/(my_component_n < my_component_o); + double my_component_eqnLeq = my_component_m <= my_component_n; + double my_component_eqnLeqCoverageParentheses = my_component_m/(my_component_n <= my_component_o); + double my_component_eqnGt = my_component_m > my_component_n; + double my_component_eqnGtCoverageParentheses = my_component_m/(my_component_n > my_component_o); + double my_component_eqnGeq = my_component_m >= my_component_n; + double my_component_eqnGeqCoverageParentheses = my_component_m/(my_component_n >= my_component_o); + double my_component_eqnAnd = my_component_m && my_component_n; + double my_component_eqnAndMultiple = my_component_m && my_component_n && my_component_o; + double my_component_p = 4.0; + double my_component_eqnAndParentheses = (my_component_m < my_component_n) && (my_component_o > my_component_p); + double my_component_eqnAndParenthesesLeftPlusWith = (my_component_m+my_component_n) && (my_component_o > my_component_p); + double my_component_eqnAndParenthesesLeftPlusWithout = my_component_m && (my_component_n > my_component_o); + double my_component_eqnAndParenthesesLeftMinusWith = (my_component_m-my_component_n) && (my_component_o > my_component_p); + double my_component_eqnAndParenthesesLeftMinusWithout = -my_component_m && (my_component_n > my_component_o); + double my_component_eqnAndParenthesesLeftPower = pow(my_component_m, my_component_n) && (my_component_o > my_component_p); + double my_component_eqnAndParenthesesLeftRoot = pow(my_component_m, 1.0/my_component_n) && (my_component_o > my_component_p); + double my_component_eqnAndParenthesesRightPlusWith = (my_component_m < my_component_n) && (my_component_o+my_component_p); + double my_component_eqnAndParenthesesRightPlusWithout = (my_component_m < my_component_n) && my_component_o; + double my_component_eqnAndParenthesesRightMinusWith = (my_component_m < my_component_n) && (my_component_o-my_component_p); + double my_component_eqnAndParenthesesRightMinusWithout = (my_component_m < my_component_n) && -my_component_o; + double my_component_eqnAndParenthesesRightPower = (my_component_m < my_component_n) && pow(my_component_o, my_component_p); + double my_component_eqnAndParenthesesRightRoot = (my_component_m < my_component_n) && pow(my_component_o, 1.0/my_component_p); + double my_component_eqnAndCoverageParentheses = my_component_m/(my_component_n && my_component_o); + double my_component_eqnOr = my_component_m || my_component_n; + double my_component_eqnOrMultiple = my_component_m || my_component_n || my_component_o; + double my_component_eqnOrParentheses = (my_component_m < my_component_n) || (my_component_o > my_component_p); + double my_component_eqnOrParenthesesLeftPlusWith = (my_component_m+my_component_n) || (my_component_o > my_component_p); + double my_component_eqnOrParenthesesLeftPlusWithout = my_component_m || (my_component_n > my_component_o); + double my_component_eqnOrParenthesesLeftMinusWith = (my_component_m-my_component_n) || (my_component_o > my_component_p); + double my_component_eqnOrParenthesesLeftMinusWithout = -my_component_m || (my_component_n > my_component_o); + double my_component_eqnOrParenthesesLeftPower = pow(my_component_m, my_component_n) || (my_component_o > my_component_p); + double my_component_eqnOrParenthesesLeftRoot = pow(my_component_m, 1.0/my_component_n) || (my_component_o > my_component_p); + double my_component_eqnOrParenthesesRightPlusWith = (my_component_m < my_component_n) || (my_component_o+my_component_p); + double my_component_eqnOrParenthesesRightPlusWithout = (my_component_m < my_component_n) || my_component_o; + double my_component_eqnOrParenthesesRightMinusWith = (my_component_m < my_component_n) || (my_component_o-my_component_p); + double my_component_eqnOrParenthesesRightMinusWithout = (my_component_m < my_component_n) || -my_component_o; + double my_component_eqnOrParenthesesRightPower = (my_component_m < my_component_n) || pow(my_component_o, my_component_p); + double my_component_eqnOrParenthesesRightRoot = (my_component_m < my_component_n) || pow(my_component_o, 1.0/my_component_p); + double my_component_eqnOrCoverageParentheses = my_component_m/(my_component_n || my_component_o); + double my_component_eqnXor = xor(my_component_m, my_component_n); + double my_component_eqnXorMultiple = xor(my_component_m, xor(my_component_n, my_component_o)); + double my_component_eqnXorParentheses = xor(my_component_m < my_component_n, my_component_o > my_component_p); + double my_component_eqnXorParenthesesLeftPlusWith = xor(my_component_m+my_component_n, my_component_o > my_component_p); + double my_component_eqnXorParenthesesLeftPlusWithout = xor(my_component_m, my_component_n > my_component_o); + double my_component_eqnXorParenthesesLeftMinusWith = xor(my_component_m-my_component_n, my_component_o > my_component_p); + double my_component_eqnXorParenthesesLeftMinusWithout = xor(-my_component_m, my_component_n > my_component_o); + double my_component_eqnXorParenthesesLeftPower = xor(pow(my_component_m, my_component_n), my_component_o > my_component_p); + double my_component_eqnXorParenthesesLeftRoot = xor(pow(my_component_m, 1.0/my_component_n), my_component_o > my_component_p); + double my_component_eqnXorParenthesesRightPlusWith = xor(my_component_m < my_component_n, my_component_o+my_component_p); + double my_component_eqnXorParenthesesRightPlusWithout = xor(my_component_m < my_component_n, my_component_o); + double my_component_eqnXorParenthesesRightMinusWith = xor(my_component_m < my_component_n, my_component_o-my_component_p); + double my_component_eqnXorParenthesesRightMinusWithout = xor(my_component_m < my_component_n, -my_component_o); + double my_component_eqnXorParenthesesRightPower = xor(my_component_m < my_component_n, pow(my_component_o, my_component_p)); + double my_component_eqnXorParenthesesRightRoot = xor(my_component_m < my_component_n, pow(my_component_o, 1.0/my_component_p)); + double my_component_eqnXorCoverageParentheses = my_component_m/xor(my_component_n, my_component_o); + double my_component_eqnNot = !my_component_m; + double my_component_eqnPlus = my_component_m+my_component_n; + double my_component_eqnPlusMultiple = my_component_m+my_component_n+my_component_o; + double my_component_eqnPlusParentheses = (my_component_m < my_component_n)+(my_component_o > my_component_p); + double my_component_eqnPlusUnary = my_component_m; + double my_component_eqnMinus = my_component_m-my_component_n; + double my_component_eqnMinusParentheses = (my_component_m < my_component_n)-(my_component_o > my_component_p); + double my_component_eqnMinusParenthesesPlusWith = (my_component_m < my_component_n)-(my_component_o+my_component_p); + double my_component_eqnMinusParenthesesPlusWithout = (my_component_m < my_component_n)-my_component_o; + double my_component_eqnMinusParenthesesDirectUnaryMinus = my_component_m-(-my_component_n); + double my_component_eqnMinusParenthesesIndirectUnaryMinus = my_component_m-(-my_component_n*my_component_o); + double my_component_eqnMinusUnary = -my_component_m; + double my_component_eqnMinusUnaryParentheses = -(my_component_m < my_component_n); + double my_component_eqnTimes = my_component_m*my_component_n; + double my_component_eqnTimesMultiple = my_component_m*my_component_n*my_component_o; + double my_component_eqnTimesParentheses = (my_component_m < my_component_n)*(my_component_o > my_component_p); + double my_component_eqnTimesParenthesesLeftPlusWith = (my_component_m+my_component_n)*(my_component_o > my_component_p); + double my_component_eqnTimesParenthesesLeftPlusWithout = my_component_m*(my_component_n > my_component_o); + double my_component_eqnTimesParenthesesLeftMinusWith = (my_component_m-my_component_n)*(my_component_o > my_component_p); + double my_component_eqnTimesParenthesesLeftMinusWithout = -my_component_m*(my_component_n > my_component_o); + double my_component_eqnTimesParenthesesRightPlusWith = (my_component_m < my_component_n)*(my_component_o+my_component_p); + double my_component_eqnTimesParenthesesRightPlusWithout = (my_component_m < my_component_n)*my_component_o; + double my_component_eqnTimesParenthesesRightMinusWith = (my_component_m < my_component_n)*(my_component_o-my_component_p); + double my_component_eqnTimesParenthesesRightMinusWithout = (my_component_m < my_component_n)*-my_component_o; + double my_component_eqnDivide = my_component_m/my_component_n; + double my_component_eqnDivideParentheses = (my_component_m < my_component_n)/(my_component_p > my_component_o); + double my_component_eqnDivideParenthesesLeftPlusWith = (my_component_m+my_component_n)/(my_component_p > my_component_o); + double my_component_eqnDivideParenthesesLeftPlusWithout = my_component_m/(my_component_o > my_component_n); + double my_component_eqnDivideParenthesesLeftMinusWith = (my_component_m-my_component_n)/(my_component_p > my_component_o); + double my_component_eqnDivideParenthesesLeftMinusWithout = -my_component_m/(my_component_o > my_component_n); + double my_component_eqnDivideParenthesesRightPlusWith = (my_component_m < my_component_n)/(my_component_o+my_component_p); + double my_component_eqnDivideParenthesesRightPlusWithout = (my_component_m < my_component_n)/my_component_o; + double my_component_eqnDivideParenthesesRightMinusWith = (my_component_m < my_component_n)/(my_component_o-my_component_p); + double my_component_eqnDivideParenthesesRightMinusWithout = (my_component_m < my_component_n)/-my_component_o; + double my_component_eqnDivideParenthesesRightTimes = (my_component_m < my_component_n)/(my_component_o*my_component_p); + double my_component_eqnDivideParenthesesRightDivide = (my_component_m < my_component_n)/(my_component_o/my_component_p); + double my_component_eqnPowerSqrt = sqrt(my_component_m); + double my_component_eqnPowerSqr = pow(my_component_m, 2.0); + double my_component_eqnPowerCube = pow(my_component_m, 3.0); + double my_component_eqnPowerCi = pow(my_component_m, my_component_n); + double my_component_eqnPowerParentheses = pow(my_component_m <= my_component_n, my_component_o >= my_component_p); + double my_component_eqnPowerParenthesesLeftPlusWith = pow(my_component_m+my_component_n, my_component_o >= my_component_p); + double my_component_eqnPowerParenthesesLeftPlusWithout = pow(my_component_m, my_component_n >= my_component_o); + double my_component_eqnPowerParenthesesLeftMinusWith = pow(my_component_m-my_component_n, my_component_o >= my_component_p); + double my_component_eqnPowerParenthesesLeftMinusWithout = pow(-my_component_m, my_component_n >= my_component_o); + double my_component_eqnPowerParenthesesLeftTimes = pow(my_component_m*my_component_n, my_component_o >= my_component_p); + double my_component_eqnPowerParenthesesLeftDivide = pow(my_component_m/my_component_n, my_component_o >= my_component_p); + double my_component_eqnPowerParenthesesRightPlusWith = pow(my_component_m <= my_component_n, my_component_o+my_component_p); + double my_component_eqnPowerParenthesesRightPlusWithout = pow(my_component_m <= my_component_n, my_component_o); + double my_component_eqnPowerParenthesesRightMinusWith = pow(my_component_m <= my_component_n, my_component_o-my_component_p); + double my_component_eqnPowerParenthesesRightMinusWithout = pow(my_component_m <= my_component_n, -my_component_o); + double my_component_eqnPowerParenthesesRightTimes = pow(my_component_m <= my_component_n, my_component_o*my_component_p); + double my_component_eqnPowerParenthesesRightDivide = pow(my_component_m <= my_component_n, my_component_o/my_component_p); + double my_component_eqnPowerParenthesesRightPower = pow(my_component_m <= my_component_n, pow(my_component_o, my_component_p)); + double my_component_eqnPowerParenthesesRightRoot = pow(my_component_m <= my_component_n, pow(my_component_o, 1.0/my_component_p)); + double my_component_eqnRootSqrt = sqrt(my_component_m); + double my_component_eqnRootSqrtOther = sqrt(my_component_m); + double my_component_eqnRootCube = pow(my_component_m, 1.0/3.0); + double my_component_eqnRootCi = pow(my_component_m, 1.0/my_component_n); + double my_component_eqnRootParentheses = pow(my_component_m < my_component_n, 1.0/(my_component_p > my_component_o)); + double my_component_eqnRootParenthesesLeftPlusWith = pow(my_component_m+my_component_n, 1.0/(my_component_p > my_component_o)); + double my_component_eqnRootParenthesesLeftPlusWithout = pow(my_component_m, 1.0/(my_component_o > my_component_n)); + double my_component_eqnRootParenthesesLeftMinusWith = pow(my_component_m-my_component_n, 1.0/(my_component_p > my_component_o)); + double my_component_eqnRootParenthesesLeftMinusWithout = pow(-my_component_m, 1.0/(my_component_o > my_component_n)); + double my_component_eqnRootParenthesesLeftTimes = pow(my_component_m*my_component_n, 1.0/(my_component_p > my_component_o)); + double my_component_eqnRootParenthesesLeftDivide = pow(my_component_m/my_component_n, 1.0/(my_component_p > my_component_o)); + double my_component_eqnRootParenthesesRightPlusWith = pow(my_component_m < my_component_n, 1.0/(my_component_o+my_component_p)); + double my_component_eqnRootParenthesesRightPlusWithout = pow(my_component_m < my_component_n, 1.0/my_component_o); + double my_component_eqnRootParenthesesRightMinusWith = pow(my_component_m < my_component_n, 1.0/(my_component_o-my_component_p)); + double my_component_eqnRootParenthesesRightMinusWithout = pow(my_component_m < my_component_n, 1.0/-my_component_o); + double my_component_eqnRootParenthesesRightTimes = pow(my_component_m < my_component_n, 1.0/(my_component_o*my_component_p)); + double my_component_eqnRootParenthesesRightDivide = pow(my_component_m < my_component_n, 1.0/(my_component_o/my_component_p)); + double my_component_eqnRootParenthesesRightPower = pow(my_component_m < my_component_n, 1.0/pow(my_component_o, my_component_p)); + double my_component_eqnRootParenthesesRightRoot = pow(my_component_m < my_component_n, 1.0/pow(my_component_o, 1.0/my_component_p)); + double my_component_eqnAbs = fabs(my_component_m); + double my_component_eqnExp = exp(my_component_m); + double my_component_eqnLn = log(my_component_m); + double my_component_eqnLog = log10(my_component_m); + double my_component_eqnLog2 = log(my_component_m)/log(2.0); + double my_component_eqnLog10 = log10(my_component_m); + double my_component_eqnLogCi = log(my_component_m)/log(my_component_n); + double my_component_eqnCeiling = ceil(my_component_m); + double my_component_eqnFloor = floor(my_component_m); + double my_component_eqnMin = min(my_component_m, my_component_n); + double my_component_eqnMinMultiple = min(my_component_m, min(my_component_n, my_component_o)); + double my_component_eqnMax = max(my_component_m, my_component_n); + double my_component_eqnMaxMultiple = max(my_component_m, max(my_component_n, my_component_o)); + double my_component_eqnRem = fmod(my_component_m, my_component_n); + double my_component_eqnSin = sin(my_component_m); + double my_component_eqnCos = cos(my_component_m); + double my_component_eqnTan = tan(my_component_m); + double my_component_eqnSec = sec(my_component_m); + double my_component_eqnCsc = csc(my_component_m); + double my_component_eqnCot = cot(my_component_m); + double my_component_eqnSinh = sinh(my_component_m); + double my_component_eqnCosh = cosh(my_component_m); + double my_component_eqnTanh = tanh(my_component_m); + double my_component_eqnSech = sech(my_component_m); + double my_component_eqnCsch = csch(my_component_m); + double my_component_eqnCoth = coth(my_component_m); + double my_component_eqnArcsin = asin(my_component_m); + double my_component_eqnArccos = acos(my_component_m); + double my_component_eqnArctan = atan(my_component_m); + double my_component_eqnArcsec = asec(my_component_m); + double my_component_eqnArccsc = acsc(my_component_m); + double my_component_eqnArccot = acot(my_component_m); + double my_component_eqnArcsinh = asinh(my_component_m); + double my_component_eqnArccosh = acosh(my_component_m); + double my_component_eqnArctanh = atanh(my_component_m/2.0); + double my_component_eqnArcsech = asech(my_component_m); + double my_component_eqnArccsch = acsch(my_component_m); + double my_component_eqnArccoth = acoth(2.0*my_component_m); + double my_component_eqnPiecewisePiece = (my_component_m > my_component_n)?my_component_m:NAN; + double my_component_eqnPiecewisePieceOtherwise = (my_component_m > my_component_n)?my_component_m:my_component_o; + double my_component_q = 5.0; + double my_component_r = 6.0; + double my_component_eqnPiecewisePiecePiecePiece = (my_component_m > my_component_n)?my_component_m:(my_component_o > my_component_p)?my_component_o:(my_component_q > my_component_r)?my_component_q:NAN; + double my_component_s = 7.0; + double my_component_eqnPiecewisePiecePiecePieceOtherwise = (my_component_m > my_component_n)?my_component_m:(my_component_o > my_component_p)?my_component_o:(my_component_q > my_component_r)?my_component_q:my_component_s; + double my_component_eqnWithPiecewise = 123.0+((my_component_m > my_component_n)?my_component_m:NAN); + double my_component_eqnCi = my_component_m; + double my_component_eqnCoverageForPlusOperator = (my_component_m && my_component_n)+((my_component_o > my_component_p)?my_component_n:NAN)+my_component_q+(my_component_r && my_component_s); + double my_component_eqnCoverageForMinusOperator = (my_component_m && my_component_n)-(((my_component_o > my_component_p)?my_component_n:NAN)-(my_component_q-((my_component_o > my_component_p)?my_component_n:NAN)))-(my_component_r && my_component_s); + double my_component_eqnCoverageForTimesOperator = (my_component_m && my_component_n)*((my_component_o > my_component_p)?my_component_n:NAN)*my_component_q*((my_component_o > my_component_p)?my_component_n:NAN)*(my_component_r && my_component_s); + double my_component_eqnCoverageForDivideOperator = (my_component_m && my_component_n)/(((my_component_o > my_component_p)?my_component_n:NAN)/(my_component_q/((my_component_o > my_component_p)?my_component_n:NAN))); + double my_component_eqnCoverageForAndOperator = (my_component_m || my_component_n) && xor(my_component_m, my_component_n) && ((my_component_o > my_component_p)?my_component_n:NAN) && my_component_q && ((my_component_o > my_component_p)?my_component_n:NAN) && xor(my_component_m, my_component_n) && (my_component_m || my_component_n); + double my_component_eqnCoverageForOrOperator = (my_component_m && my_component_n) || xor(my_component_m, my_component_n) || ((my_component_o > my_component_p)?my_component_n:NAN) || my_component_q || ((my_component_o > my_component_p)?my_component_n:NAN) || xor(my_component_m, my_component_n) || (my_component_m && my_component_n); + double my_component_eqnCoverageForXorOperator = xor(my_component_m && my_component_n, xor(my_component_m || my_component_n, xor((my_component_o > my_component_p)?my_component_n:NAN, xor(xor(xor(my_component_q, (my_component_o > my_component_p)?my_component_n:NAN), my_component_m || my_component_n), my_component_m && my_component_n)))); + double my_component_eqnCoverageForPowerOperator = pow(my_component_m && my_component_n, pow((my_component_o > my_component_p)?my_component_n:NAN, pow(pow(my_component_q, (my_component_o > my_component_p)?my_component_n:NAN), my_component_m && my_component_n))); + double my_component_eqnCoverageForRootOperator = pow(pow(pow(my_component_m && my_component_n, 1.0/pow((my_component_o > my_component_p)?my_component_n:NAN, 1.0/my_component_q)), 1.0/((my_component_o > my_component_p)?my_component_n:NAN)), 1.0/(my_component_m && my_component_n)); + double my_component_eqnCoverageForMinusUnary = -(my_component_m && my_component_n)+-((my_component_o > my_component_p)?my_component_n:NAN); + findRoot0(voi, states, rates, constants, computedConstants, algebraic); +} diff --git a/tests/resources/coverage/generator/model.no.tracking.h b/tests/resources/coverage/generator/model.no.tracking.h new file mode 100644 index 0000000000..2b2081ff85 --- /dev/null +++ b/tests/resources/coverage/generator/model.no.tracking.h @@ -0,0 +1,37 @@ +/* The content of this file was generated using the C profile of libCellML 0.6.0. */ + +#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_COUNT; + +typedef struct { + char name[38]; + char units[14]; + char component[13]; +} 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 * createAlgebraicArray(); + +void deleteArray(double *array); + +void initialiseVariables(double *states, double *rates, double *constants, double *computedConstants, double *algebraic); +void computeComputedConstants(double *constants, double *computedConstants); +void computeRates(double voi, double *states, double *rates, double *constants, double *computedConstants, double *algebraic); +void computeVariables(double voi, double *states, double *rates, double *constants, double *computedConstants, double *algebraic); diff --git a/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.algebraic.variables.c b/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.algebraic.variables.c new file mode 100644 index 0000000000..e1a239c603 --- /dev/null +++ b/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.algebraic.variables.c @@ -0,0 +1,131 @@ +/* The content of this file was generated using the C profile of libCellML 0.6.0. */ + +#include "model.untracked.algebraic.variables.h" + +#include +#include + +const char VERSION[] = "0.6.0"; +const char LIBCELLML_VERSION[] = "0.6.0"; + +const size_t STATE_COUNT = 4; +const size_t CONSTANT_COUNT = 5; +const size_t COMPUTED_CONSTANT_COUNT = 3; +const size_t ALGEBRAIC_COUNT = 0; + +const VariableInfo VOI_INFO = {"time", "millisecond", "environment"}; + +const VariableInfo STATE_INFO[] = { + {"V", "millivolt", "membrane"}, + {"h", "dimensionless", "sodium_channel_h_gate"}, + {"m", "dimensionless", "sodium_channel_m_gate"}, + {"n", "dimensionless", "potassium_channel_n_gate"} +}; + +const VariableInfo CONSTANT_INFO[] = { + {"Cm", "microF_per_cm2", "membrane"}, + {"E_R", "millivolt", "membrane"}, + {"g_L", "milliS_per_cm2", "leakage_current"}, + {"g_Na", "milliS_per_cm2", "sodium_channel"}, + {"g_K", "milliS_per_cm2", "potassium_channel"} +}; + +const VariableInfo COMPUTED_CONSTANT_INFO[] = { + {"E_L", "millivolt", "leakage_current"}, + {"E_Na", "millivolt", "sodium_channel"}, + {"E_K", "millivolt", "potassium_channel"} +}; + +const VariableInfo ALGEBRAIC_INFO[] = { +}; + +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 * createAlgebraicArray() +{ + double *res = (double *) malloc(ALGEBRAIC_COUNT*sizeof(double)); + + for (size_t i = 0; i < ALGEBRAIC_COUNT; ++i) { + res[i] = NAN; + } + + return res; +} + +void deleteArray(double *array) +{ + free(array); +} + +void initialiseVariables(double *states, double *rates, double *constants, double *computedConstants, double *algebraic) +{ + states[0] = 0.0; + states[1] = 0.6; + states[2] = 0.05; + states[3] = 0.325; + constants[0] = 1.0; + constants[1] = 0.0; + constants[2] = 0.3; + constants[3] = 120.0; + constants[4] = 36.0; +} + +void computeComputedConstants(double *constants, double *computedConstants) +{ + computedConstants[0] = constants[1]-10.613; + computedConstants[1] = constants[1]-115.0; + computedConstants[2] = constants[1]+12.0; +} + +void computeRates(double voi, double *states, double *rates, double *constants, double *computedConstants, double *algebraic) +{ + double membrane_i_Stim = ((voi >= 10.0) && (voi <= 10.5))?-20.0:0.0; + double leakage_current_i_L = constants[2]*(states[0]-computedConstants[0]); + double potassium_channel_i_K = constants[4]*pow(states[3], 4.0)*(states[0]-computedConstants[2]); + double sodium_channel_i_Na = constants[3]*pow(states[2], 3.0)*states[1]*(states[0]-computedConstants[1]); + rates[0] = -(-membrane_i_Stim+sodium_channel_i_Na+potassium_channel_i_K+leakage_current_i_L)/constants[0]; + double sodium_channel_m_gate_alpha_m = 0.1*(states[0]+25.0)/(exp((states[0]+25.0)/10.0)-1.0); + double sodium_channel_m_gate_beta_m = 4.0*exp(states[0]/18.0); + rates[2] = sodium_channel_m_gate_alpha_m*(1.0-states[2])-sodium_channel_m_gate_beta_m*states[2]; + double sodium_channel_h_gate_alpha_h = 0.07*exp(states[0]/20.0); + double sodium_channel_h_gate_beta_h = 1.0/(exp((states[0]+30.0)/10.0)+1.0); + rates[1] = sodium_channel_h_gate_alpha_h*(1.0-states[1])-sodium_channel_h_gate_beta_h*states[1]; + double potassium_channel_n_gate_alpha_n = 0.01*(states[0]+10.0)/(exp((states[0]+10.0)/10.0)-1.0); + double potassium_channel_n_gate_beta_n = 0.125*exp(states[0]/80.0); + rates[3] = potassium_channel_n_gate_alpha_n*(1.0-states[3])-potassium_channel_n_gate_beta_n*states[3]; +} + +void computeVariables(double voi, double *states, double *rates, double *constants, double *computedConstants, double *algebraic) +{ +} diff --git a/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.no.tracking.h b/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.algebraic.variables.h similarity index 100% rename from tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.no.tracking.h rename to tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.algebraic.variables.h diff --git a/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.algebraic.variables.py b/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.algebraic.variables.py new file mode 100644 index 0000000000..3c3ae4c38e --- /dev/null +++ b/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.algebraic.variables.py @@ -0,0 +1,106 @@ +# The content of this file was generated using the Python profile of libCellML 0.6.0. + +from enum import Enum +from math import * + + +__version__ = "0.5.0" +LIBCELLML_VERSION = "0.6.0" + +STATE_COUNT = 4 +CONSTANT_COUNT = 5 +COMPUTED_CONSTANT_COUNT = 3 +ALGEBRAIC_COUNT = 0 + +VOI_INFO = {"name": "time", "units": "millisecond", "component": "environment"} + +STATE_INFO = [ + {"name": "V", "units": "millivolt", "component": "membrane"}, + {"name": "h", "units": "dimensionless", "component": "sodium_channel_h_gate"}, + {"name": "m", "units": "dimensionless", "component": "sodium_channel_m_gate"}, + {"name": "n", "units": "dimensionless", "component": "potassium_channel_n_gate"} +] + +CONSTANT_INFO = [ + {"name": "Cm", "units": "microF_per_cm2", "component": "membrane"}, + {"name": "E_R", "units": "millivolt", "component": "membrane"}, + {"name": "g_L", "units": "milliS_per_cm2", "component": "leakage_current"}, + {"name": "g_Na", "units": "milliS_per_cm2", "component": "sodium_channel"}, + {"name": "g_K", "units": "milliS_per_cm2", "component": "potassium_channel"} +] + +COMPUTED_CONSTANT_INFO = [ + {"name": "E_L", "units": "millivolt", "component": "leakage_current"}, + {"name": "E_Na", "units": "millivolt", "component": "sodium_channel"}, + {"name": "E_K", "units": "millivolt", "component": "potassium_channel"} +] + +ALGEBRAIC_INFO = [ +] + + +def leq_func(x, y): + return 1.0 if x <= y else 0.0 + + +def geq_func(x, y): + return 1.0 if x >= y else 0.0 + + +def and_func(x, y): + return 1.0 if bool(x) & bool(y) else 0.0 + + +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_array(): + return [nan]*ALGEBRAIC_COUNT + + +def initialise_variables(states, rates, constants, computed_constants, algebraic): + states[0] = 0.0 + states[1] = 0.6 + states[2] = 0.05 + states[3] = 0.325 + constants[0] = 1.0 + constants[1] = 0.0 + constants[2] = 0.3 + constants[3] = 120.0 + constants[4] = 36.0 + + +def compute_computed_constants(constants, computed_constants): + computed_constants[0] = constants[1]-10.613 + computed_constants[1] = constants[1]-115.0 + computed_constants[2] = constants[1]+12.0 + + +def compute_rates(voi, states, rates, constants, computed_constants, algebraic): + membrane_i_Stim = -20.0 if and_func(geq_func(voi, 10.0), leq_func(voi, 10.5)) else 0.0 + leakage_current_i_L = constants[2]*(states[0]-computed_constants[0]) + potassium_channel_i_K = constants[4]*pow(states[3], 4.0)*(states[0]-computed_constants[2]) + sodium_channel_i_Na = constants[3]*pow(states[2], 3.0)*states[1]*(states[0]-computed_constants[1]) + rates[0] = -(-membrane_i_Stim+sodium_channel_i_Na+potassium_channel_i_K+leakage_current_i_L)/constants[0] + sodium_channel_m_gate_alpha_m = 0.1*(states[0]+25.0)/(exp((states[0]+25.0)/10.0)-1.0) + sodium_channel_m_gate_beta_m = 4.0*exp(states[0]/18.0) + rates[2] = sodium_channel_m_gate_alpha_m*(1.0-states[2])-sodium_channel_m_gate_beta_m*states[2] + sodium_channel_h_gate_alpha_h = 0.07*exp(states[0]/20.0) + sodium_channel_h_gate_beta_h = 1.0/(exp((states[0]+30.0)/10.0)+1.0) + rates[1] = sodium_channel_h_gate_alpha_h*(1.0-states[1])-sodium_channel_h_gate_beta_h*states[1] + potassium_channel_n_gate_alpha_n = 0.01*(states[0]+10.0)/(exp((states[0]+10.0)/10.0)-1.0) + potassium_channel_n_gate_beta_n = 0.125*exp(states[0]/80.0) + rates[3] = potassium_channel_n_gate_alpha_n*(1.0-states[3])-potassium_channel_n_gate_beta_n*states[3] + + +def compute_variables(voi, states, rates, constants, computed_constants, algebraic): + pass diff --git a/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.computed.constants.c b/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.computed.constants.c new file mode 100644 index 0000000000..8bbf9ae069 --- /dev/null +++ b/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.computed.constants.c @@ -0,0 +1,150 @@ +/* The content of this file was generated using the C profile of libCellML 0.6.0. */ + +#include "model.untracked.computed.constants.h" + +#include +#include + +const char VERSION[] = "0.6.0"; +const char LIBCELLML_VERSION[] = "0.6.0"; + +const size_t STATE_COUNT = 4; +const size_t CONSTANT_COUNT = 5; +const size_t COMPUTED_CONSTANT_COUNT = 0; +const size_t ALGEBRAIC_COUNT = 10; + +const VariableInfo VOI_INFO = {"time", "millisecond", "environment"}; + +const VariableInfo STATE_INFO[] = { + {"V", "millivolt", "membrane"}, + {"h", "dimensionless", "sodium_channel_h_gate"}, + {"m", "dimensionless", "sodium_channel_m_gate"}, + {"n", "dimensionless", "potassium_channel_n_gate"} +}; + +const VariableInfo CONSTANT_INFO[] = { + {"Cm", "microF_per_cm2", "membrane"}, + {"E_R", "millivolt", "membrane"}, + {"g_L", "milliS_per_cm2", "leakage_current"}, + {"g_Na", "milliS_per_cm2", "sodium_channel"}, + {"g_K", "milliS_per_cm2", "potassium_channel"} +}; + +const VariableInfo COMPUTED_CONSTANT_INFO[] = { +}; + +const VariableInfo ALGEBRAIC_INFO[] = { + {"i_Stim", "microA_per_cm2", "membrane"}, + {"i_L", "microA_per_cm2", "leakage_current"}, + {"i_K", "microA_per_cm2", "potassium_channel"}, + {"i_Na", "microA_per_cm2", "sodium_channel"}, + {"alpha_m", "per_millisecond", "sodium_channel_m_gate"}, + {"beta_m", "per_millisecond", "sodium_channel_m_gate"}, + {"alpha_h", "per_millisecond", "sodium_channel_h_gate"}, + {"beta_h", "per_millisecond", "sodium_channel_h_gate"}, + {"alpha_n", "per_millisecond", "potassium_channel_n_gate"}, + {"beta_n", "per_millisecond", "potassium_channel_n_gate"} +}; + +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 * createAlgebraicArray() +{ + double *res = (double *) malloc(ALGEBRAIC_COUNT*sizeof(double)); + + for (size_t i = 0; i < ALGEBRAIC_COUNT; ++i) { + res[i] = NAN; + } + + return res; +} + +void deleteArray(double *array) +{ + free(array); +} + +void initialiseVariables(double *states, double *rates, double *constants, double *computedConstants, double *algebraic) +{ + states[0] = 0.0; + states[1] = 0.6; + states[2] = 0.05; + states[3] = 0.325; + constants[0] = 1.0; + constants[1] = 0.0; + constants[2] = 0.3; + constants[3] = 120.0; + constants[4] = 36.0; +} + +void computeComputedConstants(double *constants, double *computedConstants) +{ +} + +void computeRates(double voi, double *states, double *rates, double *constants, double *computedConstants, double *algebraic) +{ + algebraic[0] = ((voi >= 10.0) && (voi <= 10.5))?-20.0:0.0; + double leakage_current_E_L = constants[1]-10.613; + algebraic[1] = constants[2]*(states[0]-leakage_current_E_L); + double potassium_channel_E_K = constants[1]+12.0; + algebraic[2] = constants[4]*pow(states[3], 4.0)*(states[0]-potassium_channel_E_K); + double sodium_channel_E_Na = constants[1]-115.0; + algebraic[3] = constants[3]*pow(states[2], 3.0)*states[1]*(states[0]-sodium_channel_E_Na); + rates[0] = -(-algebraic[0]+algebraic[3]+algebraic[2]+algebraic[1])/constants[0]; + algebraic[4] = 0.1*(states[0]+25.0)/(exp((states[0]+25.0)/10.0)-1.0); + algebraic[5] = 4.0*exp(states[0]/18.0); + rates[2] = algebraic[4]*(1.0-states[2])-algebraic[5]*states[2]; + algebraic[6] = 0.07*exp(states[0]/20.0); + algebraic[7] = 1.0/(exp((states[0]+30.0)/10.0)+1.0); + rates[1] = algebraic[6]*(1.0-states[1])-algebraic[7]*states[1]; + algebraic[8] = 0.01*(states[0]+10.0)/(exp((states[0]+10.0)/10.0)-1.0); + algebraic[9] = 0.125*exp(states[0]/80.0); + rates[3] = algebraic[8]*(1.0-states[3])-algebraic[9]*states[3]; +} + +void computeVariables(double voi, double *states, double *rates, double *constants, double *computedConstants, double *algebraic) +{ + double leakage_current_E_L = constants[1]-10.613; + algebraic[1] = constants[2]*(states[0]-leakage_current_E_L); + double sodium_channel_E_Na = constants[1]-115.0; + algebraic[3] = constants[3]*pow(states[2], 3.0)*states[1]*(states[0]-sodium_channel_E_Na); + algebraic[4] = 0.1*(states[0]+25.0)/(exp((states[0]+25.0)/10.0)-1.0); + algebraic[5] = 4.0*exp(states[0]/18.0); + algebraic[6] = 0.07*exp(states[0]/20.0); + algebraic[7] = 1.0/(exp((states[0]+30.0)/10.0)+1.0); + double potassium_channel_E_K = constants[1]+12.0; + algebraic[2] = constants[4]*pow(states[3], 4.0)*(states[0]-potassium_channel_E_K); + algebraic[8] = 0.01*(states[0]+10.0)/(exp((states[0]+10.0)/10.0)-1.0); + algebraic[9] = 0.125*exp(states[0]/80.0); +} diff --git a/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.computed.constants.h b/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.computed.constants.h new file mode 100644 index 0000000000..5d3f4e744d --- /dev/null +++ b/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.computed.constants.h @@ -0,0 +1,37 @@ +/* The content of this file was generated using the C profile of libCellML 0.6.0. */ + +#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_COUNT; + +typedef struct { + char name[8]; + char units[16]; + char component[25]; +} 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 * createAlgebraicArray(); + +void deleteArray(double *array); + +void initialiseVariables(double *states, double *rates, double *constants, double *computedConstants, double *algebraic); +void computeComputedConstants(double *constants, double *computedConstants); +void computeRates(double voi, double *states, double *rates, double *constants, double *computedConstants, double *algebraic); +void computeVariables(double voi, double *states, double *rates, double *constants, double *computedConstants, double *algebraic); diff --git a/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.computed.constants.py b/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.computed.constants.py new file mode 100644 index 0000000000..e3b68e47c6 --- /dev/null +++ b/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.computed.constants.py @@ -0,0 +1,125 @@ +# The content of this file was generated using the Python profile of libCellML 0.6.0. + +from enum import Enum +from math import * + + +__version__ = "0.5.0" +LIBCELLML_VERSION = "0.6.0" + +STATE_COUNT = 4 +CONSTANT_COUNT = 5 +COMPUTED_CONSTANT_COUNT = 0 +ALGEBRAIC_COUNT = 10 + +VOI_INFO = {"name": "time", "units": "millisecond", "component": "environment"} + +STATE_INFO = [ + {"name": "V", "units": "millivolt", "component": "membrane"}, + {"name": "h", "units": "dimensionless", "component": "sodium_channel_h_gate"}, + {"name": "m", "units": "dimensionless", "component": "sodium_channel_m_gate"}, + {"name": "n", "units": "dimensionless", "component": "potassium_channel_n_gate"} +] + +CONSTANT_INFO = [ + {"name": "Cm", "units": "microF_per_cm2", "component": "membrane"}, + {"name": "E_R", "units": "millivolt", "component": "membrane"}, + {"name": "g_L", "units": "milliS_per_cm2", "component": "leakage_current"}, + {"name": "g_Na", "units": "milliS_per_cm2", "component": "sodium_channel"}, + {"name": "g_K", "units": "milliS_per_cm2", "component": "potassium_channel"} +] + +COMPUTED_CONSTANT_INFO = [ +] + +ALGEBRAIC_INFO = [ + {"name": "i_Stim", "units": "microA_per_cm2", "component": "membrane"}, + {"name": "i_L", "units": "microA_per_cm2", "component": "leakage_current"}, + {"name": "i_K", "units": "microA_per_cm2", "component": "potassium_channel"}, + {"name": "i_Na", "units": "microA_per_cm2", "component": "sodium_channel"}, + {"name": "alpha_m", "units": "per_millisecond", "component": "sodium_channel_m_gate"}, + {"name": "beta_m", "units": "per_millisecond", "component": "sodium_channel_m_gate"}, + {"name": "alpha_h", "units": "per_millisecond", "component": "sodium_channel_h_gate"}, + {"name": "beta_h", "units": "per_millisecond", "component": "sodium_channel_h_gate"}, + {"name": "alpha_n", "units": "per_millisecond", "component": "potassium_channel_n_gate"}, + {"name": "beta_n", "units": "per_millisecond", "component": "potassium_channel_n_gate"} +] + + +def leq_func(x, y): + return 1.0 if x <= y else 0.0 + + +def geq_func(x, y): + return 1.0 if x >= y else 0.0 + + +def and_func(x, y): + return 1.0 if bool(x) & bool(y) else 0.0 + + +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_array(): + return [nan]*ALGEBRAIC_COUNT + + +def initialise_variables(states, rates, constants, computed_constants, algebraic): + states[0] = 0.0 + states[1] = 0.6 + states[2] = 0.05 + states[3] = 0.325 + constants[0] = 1.0 + constants[1] = 0.0 + constants[2] = 0.3 + constants[3] = 120.0 + constants[4] = 36.0 + + +def compute_computed_constants(constants, computed_constants): + pass + + +def compute_rates(voi, states, rates, constants, computed_constants, algebraic): + algebraic[0] = -20.0 if and_func(geq_func(voi, 10.0), leq_func(voi, 10.5)) else 0.0 + leakage_current_E_L = constants[1]-10.613 + algebraic[1] = constants[2]*(states[0]-leakage_current_E_L) + potassium_channel_E_K = constants[1]+12.0 + algebraic[2] = constants[4]*pow(states[3], 4.0)*(states[0]-potassium_channel_E_K) + sodium_channel_E_Na = constants[1]-115.0 + algebraic[3] = constants[3]*pow(states[2], 3.0)*states[1]*(states[0]-sodium_channel_E_Na) + rates[0] = -(-algebraic[0]+algebraic[3]+algebraic[2]+algebraic[1])/constants[0] + algebraic[4] = 0.1*(states[0]+25.0)/(exp((states[0]+25.0)/10.0)-1.0) + algebraic[5] = 4.0*exp(states[0]/18.0) + rates[2] = algebraic[4]*(1.0-states[2])-algebraic[5]*states[2] + algebraic[6] = 0.07*exp(states[0]/20.0) + algebraic[7] = 1.0/(exp((states[0]+30.0)/10.0)+1.0) + rates[1] = algebraic[6]*(1.0-states[1])-algebraic[7]*states[1] + algebraic[8] = 0.01*(states[0]+10.0)/(exp((states[0]+10.0)/10.0)-1.0) + algebraic[9] = 0.125*exp(states[0]/80.0) + rates[3] = algebraic[8]*(1.0-states[3])-algebraic[9]*states[3] + + +def compute_variables(voi, states, rates, constants, computed_constants, algebraic): + leakage_current_E_L = constants[1]-10.613 + algebraic[1] = constants[2]*(states[0]-leakage_current_E_L) + sodium_channel_E_Na = constants[1]-115.0 + algebraic[3] = constants[3]*pow(states[2], 3.0)*states[1]*(states[0]-sodium_channel_E_Na) + algebraic[4] = 0.1*(states[0]+25.0)/(exp((states[0]+25.0)/10.0)-1.0) + algebraic[5] = 4.0*exp(states[0]/18.0) + algebraic[6] = 0.07*exp(states[0]/20.0) + algebraic[7] = 1.0/(exp((states[0]+30.0)/10.0)+1.0) + potassium_channel_E_K = constants[1]+12.0 + algebraic[2] = constants[4]*pow(states[3], 4.0)*(states[0]-potassium_channel_E_K) + algebraic[8] = 0.01*(states[0]+10.0)/(exp((states[0]+10.0)/10.0)-1.0) + algebraic[9] = 0.125*exp(states[0]/80.0) diff --git a/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.constants.c b/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.constants.c new file mode 100644 index 0000000000..fcb58e454f --- /dev/null +++ b/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.constants.c @@ -0,0 +1,148 @@ +/* The content of this file was generated using the C profile of libCellML 0.6.0. */ + +#include "model.untracked.constants.h" + +#include +#include + +const char VERSION[] = "0.6.0"; +const char LIBCELLML_VERSION[] = "0.6.0"; + +const size_t STATE_COUNT = 4; +const size_t CONSTANT_COUNT = 0; +const size_t COMPUTED_CONSTANT_COUNT = 3; +const size_t ALGEBRAIC_COUNT = 10; + +const VariableInfo VOI_INFO = {"time", "millisecond", "environment"}; + +const VariableInfo STATE_INFO[] = { + {"V", "millivolt", "membrane"}, + {"h", "dimensionless", "sodium_channel_h_gate"}, + {"m", "dimensionless", "sodium_channel_m_gate"}, + {"n", "dimensionless", "potassium_channel_n_gate"} +}; + +const VariableInfo CONSTANT_INFO[] = { +}; + +const VariableInfo COMPUTED_CONSTANT_INFO[] = { + {"E_L", "millivolt", "leakage_current"}, + {"E_Na", "millivolt", "sodium_channel"}, + {"E_K", "millivolt", "potassium_channel"} +}; + +const VariableInfo ALGEBRAIC_INFO[] = { + {"i_Stim", "microA_per_cm2", "membrane"}, + {"i_L", "microA_per_cm2", "leakage_current"}, + {"i_K", "microA_per_cm2", "potassium_channel"}, + {"i_Na", "microA_per_cm2", "sodium_channel"}, + {"alpha_m", "per_millisecond", "sodium_channel_m_gate"}, + {"beta_m", "per_millisecond", "sodium_channel_m_gate"}, + {"alpha_h", "per_millisecond", "sodium_channel_h_gate"}, + {"beta_h", "per_millisecond", "sodium_channel_h_gate"}, + {"alpha_n", "per_millisecond", "potassium_channel_n_gate"}, + {"beta_n", "per_millisecond", "potassium_channel_n_gate"} +}; + +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 * createAlgebraicArray() +{ + double *res = (double *) malloc(ALGEBRAIC_COUNT*sizeof(double)); + + for (size_t i = 0; i < ALGEBRAIC_COUNT; ++i) { + res[i] = NAN; + } + + return res; +} + +void deleteArray(double *array) +{ + free(array); +} + +void initialiseVariables(double *states, double *rates, double *constants, double *computedConstants, double *algebraic) +{ + states[0] = 0.0; + states[1] = 0.6; + states[2] = 0.05; + states[3] = 0.325; +} + +void computeComputedConstants(double *constants, double *computedConstants) +{ + double membrane_E_R = 0.0; + computedConstants[0] = membrane_E_R-10.613; + computedConstants[1] = membrane_E_R-115.0; + computedConstants[2] = membrane_E_R+12.0; +} + +void computeRates(double voi, double *states, double *rates, double *constants, double *computedConstants, double *algebraic) +{ + double membrane_Cm = 1.0; + algebraic[0] = ((voi >= 10.0) && (voi <= 10.5))?-20.0:0.0; + double leakage_current_g_L = 0.3; + algebraic[1] = leakage_current_g_L*(states[0]-computedConstants[0]); + double potassium_channel_g_K = 36.0; + algebraic[2] = potassium_channel_g_K*pow(states[3], 4.0)*(states[0]-computedConstants[2]); + double sodium_channel_g_Na = 120.0; + algebraic[3] = sodium_channel_g_Na*pow(states[2], 3.0)*states[1]*(states[0]-computedConstants[1]); + rates[0] = -(-algebraic[0]+algebraic[3]+algebraic[2]+algebraic[1])/membrane_Cm; + algebraic[4] = 0.1*(states[0]+25.0)/(exp((states[0]+25.0)/10.0)-1.0); + algebraic[5] = 4.0*exp(states[0]/18.0); + rates[2] = algebraic[4]*(1.0-states[2])-algebraic[5]*states[2]; + algebraic[6] = 0.07*exp(states[0]/20.0); + algebraic[7] = 1.0/(exp((states[0]+30.0)/10.0)+1.0); + rates[1] = algebraic[6]*(1.0-states[1])-algebraic[7]*states[1]; + algebraic[8] = 0.01*(states[0]+10.0)/(exp((states[0]+10.0)/10.0)-1.0); + algebraic[9] = 0.125*exp(states[0]/80.0); + rates[3] = algebraic[8]*(1.0-states[3])-algebraic[9]*states[3]; +} + +void computeVariables(double voi, double *states, double *rates, double *constants, double *computedConstants, double *algebraic) +{ + double leakage_current_g_L = 0.3; + algebraic[1] = leakage_current_g_L*(states[0]-computedConstants[0]); + double sodium_channel_g_Na = 120.0; + algebraic[3] = sodium_channel_g_Na*pow(states[2], 3.0)*states[1]*(states[0]-computedConstants[1]); + algebraic[4] = 0.1*(states[0]+25.0)/(exp((states[0]+25.0)/10.0)-1.0); + algebraic[5] = 4.0*exp(states[0]/18.0); + algebraic[6] = 0.07*exp(states[0]/20.0); + algebraic[7] = 1.0/(exp((states[0]+30.0)/10.0)+1.0); + double potassium_channel_g_K = 36.0; + algebraic[2] = potassium_channel_g_K*pow(states[3], 4.0)*(states[0]-computedConstants[2]); + algebraic[8] = 0.01*(states[0]+10.0)/(exp((states[0]+10.0)/10.0)-1.0); + algebraic[9] = 0.125*exp(states[0]/80.0); +} diff --git a/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.constants.h b/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.constants.h new file mode 100644 index 0000000000..5d3f4e744d --- /dev/null +++ b/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.constants.h @@ -0,0 +1,37 @@ +/* The content of this file was generated using the C profile of libCellML 0.6.0. */ + +#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_COUNT; + +typedef struct { + char name[8]; + char units[16]; + char component[25]; +} 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 * createAlgebraicArray(); + +void deleteArray(double *array); + +void initialiseVariables(double *states, double *rates, double *constants, double *computedConstants, double *algebraic); +void computeComputedConstants(double *constants, double *computedConstants); +void computeRates(double voi, double *states, double *rates, double *constants, double *computedConstants, double *algebraic); +void computeVariables(double voi, double *states, double *rates, double *constants, double *computedConstants, double *algebraic); diff --git a/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.constants.py b/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.constants.py new file mode 100644 index 0000000000..982e87c4a7 --- /dev/null +++ b/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.constants.py @@ -0,0 +1,122 @@ +# The content of this file was generated using the Python profile of libCellML 0.6.0. + +from enum import Enum +from math import * + + +__version__ = "0.5.0" +LIBCELLML_VERSION = "0.6.0" + +STATE_COUNT = 4 +CONSTANT_COUNT = 0 +COMPUTED_CONSTANT_COUNT = 3 +ALGEBRAIC_COUNT = 10 + +VOI_INFO = {"name": "time", "units": "millisecond", "component": "environment"} + +STATE_INFO = [ + {"name": "V", "units": "millivolt", "component": "membrane"}, + {"name": "h", "units": "dimensionless", "component": "sodium_channel_h_gate"}, + {"name": "m", "units": "dimensionless", "component": "sodium_channel_m_gate"}, + {"name": "n", "units": "dimensionless", "component": "potassium_channel_n_gate"} +] + +CONSTANT_INFO = [ +] + +COMPUTED_CONSTANT_INFO = [ + {"name": "E_L", "units": "millivolt", "component": "leakage_current"}, + {"name": "E_Na", "units": "millivolt", "component": "sodium_channel"}, + {"name": "E_K", "units": "millivolt", "component": "potassium_channel"} +] + +ALGEBRAIC_INFO = [ + {"name": "i_Stim", "units": "microA_per_cm2", "component": "membrane"}, + {"name": "i_L", "units": "microA_per_cm2", "component": "leakage_current"}, + {"name": "i_K", "units": "microA_per_cm2", "component": "potassium_channel"}, + {"name": "i_Na", "units": "microA_per_cm2", "component": "sodium_channel"}, + {"name": "alpha_m", "units": "per_millisecond", "component": "sodium_channel_m_gate"}, + {"name": "beta_m", "units": "per_millisecond", "component": "sodium_channel_m_gate"}, + {"name": "alpha_h", "units": "per_millisecond", "component": "sodium_channel_h_gate"}, + {"name": "beta_h", "units": "per_millisecond", "component": "sodium_channel_h_gate"}, + {"name": "alpha_n", "units": "per_millisecond", "component": "potassium_channel_n_gate"}, + {"name": "beta_n", "units": "per_millisecond", "component": "potassium_channel_n_gate"} +] + + +def leq_func(x, y): + return 1.0 if x <= y else 0.0 + + +def geq_func(x, y): + return 1.0 if x >= y else 0.0 + + +def and_func(x, y): + return 1.0 if bool(x) & bool(y) else 0.0 + + +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_array(): + return [nan]*ALGEBRAIC_COUNT + + +def initialise_variables(states, rates, constants, computed_constants, algebraic): + states[0] = 0.0 + states[1] = 0.6 + states[2] = 0.05 + states[3] = 0.325 + + +def compute_computed_constants(constants, computed_constants): + membrane_E_R = 0.0 + computed_constants[0] = membrane_E_R-10.613 + computed_constants[1] = membrane_E_R-115.0 + computed_constants[2] = membrane_E_R+12.0 + + +def compute_rates(voi, states, rates, constants, computed_constants, algebraic): + membrane_Cm = 1.0 + algebraic[0] = -20.0 if and_func(geq_func(voi, 10.0), leq_func(voi, 10.5)) else 0.0 + leakage_current_g_L = 0.3 + algebraic[1] = leakage_current_g_L*(states[0]-computed_constants[0]) + potassium_channel_g_K = 36.0 + algebraic[2] = potassium_channel_g_K*pow(states[3], 4.0)*(states[0]-computed_constants[2]) + sodium_channel_g_Na = 120.0 + algebraic[3] = sodium_channel_g_Na*pow(states[2], 3.0)*states[1]*(states[0]-computed_constants[1]) + rates[0] = -(-algebraic[0]+algebraic[3]+algebraic[2]+algebraic[1])/membrane_Cm + algebraic[4] = 0.1*(states[0]+25.0)/(exp((states[0]+25.0)/10.0)-1.0) + algebraic[5] = 4.0*exp(states[0]/18.0) + rates[2] = algebraic[4]*(1.0-states[2])-algebraic[5]*states[2] + algebraic[6] = 0.07*exp(states[0]/20.0) + algebraic[7] = 1.0/(exp((states[0]+30.0)/10.0)+1.0) + rates[1] = algebraic[6]*(1.0-states[1])-algebraic[7]*states[1] + algebraic[8] = 0.01*(states[0]+10.0)/(exp((states[0]+10.0)/10.0)-1.0) + algebraic[9] = 0.125*exp(states[0]/80.0) + rates[3] = algebraic[8]*(1.0-states[3])-algebraic[9]*states[3] + + +def compute_variables(voi, states, rates, constants, computed_constants, algebraic): + leakage_current_g_L = 0.3 + algebraic[1] = leakage_current_g_L*(states[0]-computed_constants[0]) + sodium_channel_g_Na = 120.0 + algebraic[3] = sodium_channel_g_Na*pow(states[2], 3.0)*states[1]*(states[0]-computed_constants[1]) + algebraic[4] = 0.1*(states[0]+25.0)/(exp((states[0]+25.0)/10.0)-1.0) + algebraic[5] = 4.0*exp(states[0]/18.0) + algebraic[6] = 0.07*exp(states[0]/20.0) + algebraic[7] = 1.0/(exp((states[0]+30.0)/10.0)+1.0) + potassium_channel_g_K = 36.0 + algebraic[2] = potassium_channel_g_K*pow(states[3], 4.0)*(states[0]-computed_constants[2]) + algebraic[8] = 0.01*(states[0]+10.0)/(exp((states[0]+10.0)/10.0)-1.0) + algebraic[9] = 0.125*exp(states[0]/80.0) diff --git a/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.no.tracking.c b/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.variables.c similarity index 98% rename from tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.no.tracking.c rename to tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.variables.c index a116747dc3..b9e27894d1 100644 --- a/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.no.tracking.c +++ b/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.variables.c @@ -1,6 +1,6 @@ /* The content of this file was generated using the C profile of libCellML 0.6.0. */ -#include "model.h" +#include "model.untracked.variables.h" #include #include diff --git a/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.variables.h b/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.variables.h new file mode 100644 index 0000000000..5d3f4e744d --- /dev/null +++ b/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.variables.h @@ -0,0 +1,37 @@ +/* The content of this file was generated using the C profile of libCellML 0.6.0. */ + +#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_COUNT; + +typedef struct { + char name[8]; + char units[16]; + char component[25]; +} 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 * createAlgebraicArray(); + +void deleteArray(double *array); + +void initialiseVariables(double *states, double *rates, double *constants, double *computedConstants, double *algebraic); +void computeComputedConstants(double *constants, double *computedConstants); +void computeRates(double voi, double *states, double *rates, double *constants, double *computedConstants, double *algebraic); +void computeVariables(double voi, double *states, double *rates, double *constants, double *computedConstants, double *algebraic); diff --git a/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.no.tracking.py b/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.variables.py similarity index 100% rename from tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.no.tracking.py rename to tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.variables.py diff --git a/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.variables.with.externals.c b/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.variables.with.externals.c new file mode 100644 index 0000000000..12ff3c8289 --- /dev/null +++ b/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.variables.with.externals.c @@ -0,0 +1,124 @@ +/* The content of this file was generated using the C profile of libCellML 0.6.0. */ + +#include "model.untracked.variables.with.externals.h" + +#include +#include + +const char VERSION[] = "0.6.0"; +const char LIBCELLML_VERSION[] = "0.6.0"; + +const size_t STATE_COUNT = 3; +const size_t CONSTANT_COUNT = 0; +const size_t COMPUTED_CONSTANT_COUNT = 0; +const size_t ALGEBRAIC_COUNT = 0; +const size_t EXTERNAL_COUNT = 0; + +const VariableInfo VOI_INFO = {"time", "millisecond", "environment"}; + +const VariableInfo STATE_INFO[] = { + {"h", "dimensionless", "sodium_channel_h_gate"}, + {"m", "dimensionless", "sodium_channel_m_gate"}, + {"n", "dimensionless", "potassium_channel_n_gate"} +}; + +const VariableInfo CONSTANT_INFO[] = { +}; + +const VariableInfo COMPUTED_CONSTANT_INFO[] = { +}; + +const VariableInfo ALGEBRAIC_INFO[] = { +}; + +const VariableInfo EXTERNAL_INFO[] = { +}; + +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 * createAlgebraicArray() +{ + double *res = (double *) malloc(ALGEBRAIC_COUNT*sizeof(double)); + + for (size_t i = 0; i < ALGEBRAIC_COUNT; ++i) { + res[i] = NAN; + } + + return res; +} + +double * createExternalsArray() +{ + double *res = (double *) malloc(EXTERNAL_COUNT*sizeof(double)); + + for (size_t i = 0; i < EXTERNAL_COUNT; ++i) { + res[i] = NAN; + } + + return res; +} + +void deleteArray(double *array) +{ + free(array); +} + +void initialiseVariables(double *states, double *rates, double *constants, double *computedConstants, double *algebraic) +{ + states[0] = 0.6; + states[1] = 0.05; + states[2] = 0.325; +} + +void computeComputedConstants(double *constants, double *computedConstants) +{ +} + +void computeRates(double voi, double *states, double *rates, double *constants, double *computedConstants, double *algebraic, double *externals, ExternalVariable externalVariable) +{ + double membrane_V = externalVariable(voi, states, rates, constants, computedConstants, algebraic, externals, 0); + double sodium_channel_m_gate_alpha_m = 0.1*(membrane_V+25.0)/(exp((membrane_V+25.0)/10.0)-1.0); + double sodium_channel_m_gate_beta_m = 4.0*exp(membrane_V/18.0); + rates[1] = sodium_channel_m_gate_alpha_m*(1.0-states[1])-sodium_channel_m_gate_beta_m*states[1]; + double sodium_channel_h_gate_alpha_h = 0.07*exp(membrane_V/20.0); + double sodium_channel_h_gate_beta_h = 1.0/(exp((membrane_V+30.0)/10.0)+1.0); + rates[0] = sodium_channel_h_gate_alpha_h*(1.0-states[0])-sodium_channel_h_gate_beta_h*states[0]; + double potassium_channel_n_gate_alpha_n = externalVariable(voi, states, rates, constants, computedConstants, algebraic, externals, 2); + double potassium_channel_n_gate_beta_n = 0.125*exp(membrane_V/80.0); + rates[2] = potassium_channel_n_gate_alpha_n*(1.0-states[2])-potassium_channel_n_gate_beta_n*states[2]; +} + +void computeVariables(double voi, double *states, double *rates, double *constants, double *computedConstants, double *algebraic, double *externals, ExternalVariable externalVariable) +{ +} diff --git a/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.variables.with.externals.h b/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.variables.with.externals.h new file mode 100644 index 0000000000..a4fb541db7 --- /dev/null +++ b/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.variables.with.externals.h @@ -0,0 +1,42 @@ +/* The content of this file was generated using the C profile of libCellML 0.6.0. */ + +#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_COUNT; +extern const size_t EXTERNAL_COUNT; + +typedef struct { + char name[8]; + char units[16]; + char component[25]; +} 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[]; +extern const VariableInfo EXTERNAL_INFO[]; + +double * createStatesArray(); +double * createConstantsArray(); +double * createComputedConstantsArray(); +double * createAlgebraicArray(); +double * createExternalsArray(); + +void deleteArray(double *array); + +typedef double (* ExternalVariable)(double voi, double *states, double *rates, double *constants, double *computedConstants, double *algebraic, double *externals, size_t index); + +void initialiseVariables(double *states, double *rates, double *constants, double *computedConstants, double *algebraic); +void computeComputedConstants(double *constants, double *computedConstants); +void computeRates(double voi, double *states, double *rates, double *constants, double *computedConstants, double *algebraic, double *externals, ExternalVariable externalVariable); +void computeVariables(double voi, double *states, double *rates, double *constants, double *computedConstants, double *algebraic, double *externals, ExternalVariable externalVariable); diff --git a/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.variables.with.externals.py b/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.variables.with.externals.py new file mode 100644 index 0000000000..fbe64a77d1 --- /dev/null +++ b/tests/resources/generator/hodgkin_huxley_squid_axon_model_1952/model.untracked.variables.with.externals.py @@ -0,0 +1,93 @@ +# The content of this file was generated using the Python profile of libCellML 0.6.0. + +from enum import Enum +from math import * + + +__version__ = "0.5.0" +LIBCELLML_VERSION = "0.6.0" + +STATE_COUNT = 3 +CONSTANT_COUNT = 0 +COMPUTED_CONSTANT_COUNT = 0 +ALGEBRAIC_COUNT = 0 +EXTERNAL_COUNT = 0 + +VOI_INFO = {"name": "time", "units": "millisecond", "component": "environment"} + +STATE_INFO = [ + {"name": "h", "units": "dimensionless", "component": "sodium_channel_h_gate"}, + {"name": "m", "units": "dimensionless", "component": "sodium_channel_m_gate"}, + {"name": "n", "units": "dimensionless", "component": "potassium_channel_n_gate"} +] + +CONSTANT_INFO = [ +] + +COMPUTED_CONSTANT_INFO = [ +] + +ALGEBRAIC_INFO = [ +] + +EXTERNAL_INFO = [ +] + + +def leq_func(x, y): + return 1.0 if x <= y else 0.0 + + +def geq_func(x, y): + return 1.0 if x >= y else 0.0 + + +def and_func(x, y): + return 1.0 if bool(x) & bool(y) else 0.0 + + +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_array(): + return [nan]*ALGEBRAIC_COUNT + + +def create_externals_array(): + return [nan]*EXTERNAL_COUNT + + +def initialise_variables(states, rates, constants, computed_constants, algebraic): + states[0] = 0.6 + states[1] = 0.05 + states[2] = 0.325 + + +def compute_computed_constants(constants, computed_constants): + pass + + +def compute_rates(voi, states, rates, constants, computed_constants, algebraic, externals, external_variable): + membrane_V = external_variable(voi, states, rates, constants, computed_constants, algebraic, externals, 0) + sodium_channel_m_gate_alpha_m = 0.1*(membrane_V+25.0)/(exp((membrane_V+25.0)/10.0)-1.0) + sodium_channel_m_gate_beta_m = 4.0*exp(membrane_V/18.0) + rates[1] = sodium_channel_m_gate_alpha_m*(1.0-states[1])-sodium_channel_m_gate_beta_m*states[1] + sodium_channel_h_gate_alpha_h = 0.07*exp(membrane_V/20.0) + sodium_channel_h_gate_beta_h = 1.0/(exp((membrane_V+30.0)/10.0)+1.0) + rates[0] = sodium_channel_h_gate_alpha_h*(1.0-states[0])-sodium_channel_h_gate_beta_h*states[0] + potassium_channel_n_gate_alpha_n = external_variable(voi, states, rates, constants, computed_constants, algebraic, externals, 2) + potassium_channel_n_gate_beta_n = 0.125*exp(membrane_V/80.0) + rates[2] = potassium_channel_n_gate_alpha_n*(1.0-states[2])-potassium_channel_n_gate_beta_n*states[2] + + +def compute_variables(voi, states, rates, constants, computed_constants, algebraic, externals, external_variable): + pass