From d1bdc4d88b801d2f5699dd08f317ac8f04ba3962 Mon Sep 17 00:00:00 2001 From: abi-git-user Date: Mon, 16 Oct 2023 13:28:26 +1300 Subject: [PATCH] Create release v0.5.0-rc.5. --- CMakeLists.txt | 2 +- ...5.0-rc.4.rst => changelog_v0.5.0-rc.5.rst} | 9 +- docs/changelogs/index.rst | 2 +- docs/conf.in.py | 2 +- docs/index.rst | 2 +- src/analyser.cpp | 2 +- src/analysermodel.cpp | 13 +- src/analysermodel_p.h | 6 +- src/api/libcellml/analysermodel.h | 2 +- src/importer.cpp | 23 +- tests/generator/generator.cpp | 45 +++- tests/importer/model_flattening.cpp | 36 +++ .../generator/cellml_slc_example/model.py | 54 +++++ .../cellml_slc_example/slc_model.cellml | 71 ++++++ .../slc_model_units_only.cellml | 8 + .../cellml_slc_example/units_BG.cellml | 221 ++++++++++++++++++ 16 files changed, 464 insertions(+), 34 deletions(-) rename docs/changelogs/{changelog_v0.5.0-rc.4.rst => changelog_v0.5.0-rc.5.rst} (97%) create mode 100644 tests/resources/generator/cellml_slc_example/model.py create mode 100644 tests/resources/generator/cellml_slc_example/slc_model.cellml create mode 100644 tests/resources/generator/cellml_slc_example/slc_model_units_only.cellml create mode 100644 tests/resources/generator/cellml_slc_example/units_BG.cellml diff --git a/CMakeLists.txt b/CMakeLists.txt index 4151623fb9..57cb076202 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,7 @@ set(CMAKE_OSX_DEPLOYMENT_TARGET 10.15 CACHE STRING "Minimum OS X deployment vers set(PROJECT_NAME libCellML) set(PROJECT_URL https://libcellml.org) set(_PROJECT_VERSION 0.5.0) -set(PROJECT_DEVELOPER_VERSION -rc.4) +set(PROJECT_DEVELOPER_VERSION -rc.5) project(${PROJECT_NAME} VERSION ${_PROJECT_VERSION} LANGUAGES CXX) # Set policies that affect the build. diff --git a/docs/changelogs/changelog_v0.5.0-rc.4.rst b/docs/changelogs/changelog_v0.5.0-rc.5.rst similarity index 97% rename from docs/changelogs/changelog_v0.5.0-rc.4.rst rename to docs/changelogs/changelog_v0.5.0-rc.5.rst index b644ee6885..50ebda2f4a 100644 --- a/docs/changelogs/changelog_v0.5.0-rc.4.rst +++ b/docs/changelogs/changelog_v0.5.0-rc.5.rst @@ -1,10 +1,12 @@ -libCellML v0.5.0-rc.4 Changelog +libCellML v0.5.0-rc.5 Changelog =============================== Analyser -------- +* AnaylserModel: Fix loss of Units definition information by `@hsorby `_ [`#1196 `_]. * Analyser: add support for unknown variables that have been marked as external by `@agarny `_ [`#1184 `_]. +* AnalyserVariable: hold onto the owning component reference by `@agarny `_ [`#1185 `_]. * Analyser: don't optimise the order of variables and equations by `@agarny `_ [`#1090 `_]. * Analyser: reworked the analysis of a model with external variables by `@agarny `_ [`#1077 `_]. * Analyser: allow for the unknown variable to be either on the LHS or RHS of an equation by `@agarny `_ [`#1071 `_]. @@ -79,11 +81,6 @@ Miscellaneous * Analyser/Generator: replace if...else statements with switch ones wherever possible by `@agarny `_ [`#1135 `_]. * Tests: added support for libXml2 2.9.11+ by `@agarny `_ [`#1069 `_]. -No category ------------ - -* AnalyserVariable: hold onto the owning component reference by `@agarny `_ [`#1185 `_]. - Validation ---------- diff --git a/docs/changelogs/index.rst b/docs/changelogs/index.rst index 558b3c42fb..6667f80b2b 100644 --- a/docs/changelogs/index.rst +++ b/docs/changelogs/index.rst @@ -4,7 +4,7 @@ Changelogs .. toctree:: - changelog_v0.5.0-rc.4 + changelog_v0.5.0-rc.5 changelog_v0.4.0 changelog_v0.3.104 changelog_v0.3.103 diff --git a/docs/conf.in.py b/docs/conf.in.py index 14dbe95dd1..4c3330116c 100644 --- a/docs/conf.in.py +++ b/docs/conf.in.py @@ -51,7 +51,7 @@ extlinks = { # NB for deployment outside of the libcellml.org domain, you will need to include the root of the href for the # :api: shortcut here. This only works internally. - 'api': ('/documentation/api/latest/classlibcellml_1_1%s', ''), + 'api': ('/documentation/api/latest/classlibcellml_1_1%s', ''), 'buildbot': ('https://buildbot.net/%s',''), 'cellml': ('https://www.cellml.org/%s',''), 'cellml2spec': ('https://www.cellml.org/specifications/cellml_2.0%s', ''), diff --git a/docs/index.rst b/docs/index.rst index 18175b61b5..10aec54060 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -39,7 +39,7 @@ Changelogs .. toctree:: - changelogs/changelog_v0.5.0-rc.4 + changelogs/changelog_v0.5.0-rc.5 changelogs/changelog_v0.4.0 changelogs/changelog_v0.3.104 changelogs/changelog_v0.3.103 diff --git a/src/analyser.cpp b/src/analyser.cpp index 3f12f9f4dc..0764efc730 100644 --- a/src/analyser.cpp +++ b/src/analyser.cpp @@ -2324,7 +2324,7 @@ void Analyser::AnalyserImpl::analyseModel(const ModelPtr &model) // Reset a few things in case this analyser was to be used to analyse more // than one model. - mModel = AnalyserModel::AnalyserModelImpl::create(); + mModel = AnalyserModel::AnalyserModelImpl::create(model); mInternalVariables.clear(); mInternalEquations.clear(); diff --git a/src/analysermodel.cpp b/src/analysermodel.cpp index 35788e543a..1931ca3893 100644 --- a/src/analysermodel.cpp +++ b/src/analysermodel.cpp @@ -21,13 +21,18 @@ limitations under the License. namespace libcellml { -AnalyserModelPtr AnalyserModel::AnalyserModelImpl::create() +AnalyserModelPtr AnalyserModel::AnalyserModelImpl::create(const ModelPtr &model) { - return std::shared_ptr {new AnalyserModel {}}; + return std::shared_ptr {new AnalyserModel(model)}; } -AnalyserModel::AnalyserModel() - : mPimpl(new AnalyserModelImpl()) +AnalyserModel::AnalyserModelImpl::AnalyserModelImpl(const ModelPtr &model) + : mModel(model) +{ +} + +AnalyserModel::AnalyserModel(const ModelPtr &model) + : mPimpl(new AnalyserModelImpl(model)) { } diff --git a/src/analysermodel_p.h b/src/analysermodel_p.h index 3ed1939d6d..2933e8a948 100644 --- a/src/analysermodel_p.h +++ b/src/analysermodel_p.h @@ -27,6 +27,8 @@ namespace libcellml { */ struct AnalyserModel::AnalyserModelImpl { + ModelPtr mModel; + AnalyserModel::Type mType = Type::UNKNOWN; bool mHasExternalVariables = false; @@ -65,7 +67,9 @@ struct AnalyserModel::AnalyserModelImpl std::map mCachedEquivalentVariables; - static AnalyserModelPtr create(); + static AnalyserModelPtr create(const ModelPtr &model = nullptr); + + AnalyserModelImpl(const ModelPtr &model); }; } // namespace libcellml diff --git a/src/api/libcellml/analysermodel.h b/src/api/libcellml/analysermodel.h index dc8c81f9d8..e6358dcb7e 100644 --- a/src/api/libcellml/analysermodel.h +++ b/src/api/libcellml/analysermodel.h @@ -510,7 +510,7 @@ class LIBCELLML_EXPORT AnalyserModel const VariablePtr &variable2); private: - AnalyserModel(); /**< Constructor, @private. */ + AnalyserModel(const ModelPtr &model); /**< Constructor, @private. */ struct AnalyserModelImpl; AnalyserModelImpl *mPimpl; /**< Private member to implementation pointer, @private. */ diff --git a/src/importer.cpp b/src/importer.cpp index 40b7afb2a1..4b233c9d78 100644 --- a/src/importer.cpp +++ b/src/importer.cpp @@ -787,14 +787,12 @@ void retrieveUnitsDependencies(const ModelPtr &flatModel, const ModelPtr &model, auto childUnits = model->units(reference); if (childUnits->isImport()) { size_t flatModelUnitsIndex = flatModel->unitsCount(); - UnitsPtr clonedChildUnits = childUnits->clone(); - flatModel->addUnits(clonedChildUnits); - flattenUnitsImports(flatModel, clonedChildUnits, flatModelUnitsIndex, component); + flatModel->addUnits(childUnits); + flattenUnitsImports(flatModel, childUnits, flatModelUnitsIndex, component); } else { - auto clonedChildUnits = childUnits->clone(); - transferUnitsRenamingIfRequired(model, flatModel, clonedChildUnits, component); - u->setUnitAttributeReference(unitIndex, clonedChildUnits->name()); - retrieveUnitsDependencies(flatModel, model, clonedChildUnits, component); + transferUnitsRenamingIfRequired(model, flatModel, childUnits, component); + u->setUnitAttributeReference(unitIndex, childUnits->name()); + retrieveUnitsDependencies(flatModel, model, childUnits, component); } } } @@ -803,12 +801,11 @@ void retrieveUnitsDependencies(const ModelPtr &flatModel, const ModelPtr &model, void flattenUnitsImports(const ModelPtr &flatModel, const UnitsPtr &units, size_t index, const ComponentPtr &component) { auto importSource = units->importSource(); - auto importingModel = importSource->model(); - auto importedUnits = importingModel->units(units->importReference()); - auto importedUnitsCopy = importedUnits->clone(); - importedUnitsCopy->setName(units->name()); - flatModel->replaceUnits(index, importedUnitsCopy); - retrieveUnitsDependencies(flatModel, importingModel, importedUnitsCopy, component); + auto importingModelCopy = importSource->model()->clone(); + auto importedUnits = importingModelCopy->units(units->importReference()); + importedUnits->setName(units->name()); + flatModel->replaceUnits(index, importedUnits); + retrieveUnitsDependencies(flatModel, importingModelCopy, importedUnits, component); } ComponentPtr flattenComponent(const ComponentEntityPtr &parent, ComponentPtr &component, size_t index) diff --git a/tests/generator/generator.cpp b/tests/generator/generator.cpp index 36e03f3da0..2494fa8dcf 100644 --- a/tests/generator/generator.cpp +++ b/tests/generator/generator.cpp @@ -1840,19 +1840,22 @@ TEST(Generator, variableInitialisedUsingAConstant) TEST(Generator, modelOutOfScope) { - auto analyser = libcellml::Analyser::create(); + libcellml::AnalyserModelPtr analyserModel; + { + auto analyser = libcellml::Analyser::create(); auto parser = libcellml::Parser::create(); auto model = parser->parseModel(fileContents("generator/ode_multiple_dependent_odes/model.cellml")); EXPECT_EQ(size_t(0), parser->issueCount()); analyser->analyseModel(model); - } - EXPECT_EQ(size_t(0), analyser->errorCount()); + EXPECT_EQ(size_t(0), analyser->errorCount()); + + analyserModel = analyser->model(); + } - auto analyserModel = analyser->model(); auto generator = libcellml::Generator::create(); generator->setModel(analyserModel); @@ -1893,3 +1896,37 @@ TEST(Generator, unknownVariableMarkedAsExternalVariable) EXPECT_EQ(fileContents("generator/unknown_variable_as_external_variable/model.py"), generator->implementationCode()); } + +TEST(Generator, modelWithComplexUnitsOutOfScope) +{ + libcellml::AnalyserModelPtr analyserModel; + + { + auto analyser = libcellml::Analyser::create(); + auto parser = libcellml::Parser::create(); + auto importer = libcellml::Importer::create(); + auto model = parser->parseModel(fileContents("generator/cellml_slc_example/slc_model.cellml")); + + EXPECT_EQ(size_t(0), parser->issueCount()); + + importer->resolveImports(model, resourcePath("generator/cellml_slc_example")); + EXPECT_FALSE(model->hasUnresolvedImports()); + + model = importer->flattenModel(model); + + analyser->analyseModel(model); + EXPECT_EQ(size_t(0), analyser->errorCount()); + + analyserModel = analyser->model(); + } + + auto generator = libcellml::Generator::create(); + + generator->setModel(analyserModel); + + auto profile = libcellml::GeneratorProfile::create(libcellml::GeneratorProfile::Profile::PYTHON); + + generator->setProfile(profile); + + EXPECT_EQ(fileContents("generator/cellml_slc_example/model.py"), generator->implementationCode()); +} diff --git a/tests/importer/model_flattening.cpp b/tests/importer/model_flattening.cpp index d6b72fe782..43caf422ad 100644 --- a/tests/importer/model_flattening.cpp +++ b/tests/importer/model_flattening.cpp @@ -1863,3 +1863,39 @@ TEST(ModelFlattening, resolveImportsInvalidInput) EXPECT_EQ(size_t(1), importer->issueCount()); EXPECT_EQ("Cannot resolve imports for null model.", importer->issue(0)->description()); } + +TEST(ModelFlattening, flatteningImportedUnitsThatNeedEquivalence) +{ + const std::string e = + "\n" + "\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + "\n"; + + auto parser = libcellml::Parser::create(); + auto importer = libcellml::Importer::create(); + + auto model = parser->parseModel(fileContents("generator/cellml_slc_example/slc_model_units_only.cellml")); + + EXPECT_EQ(size_t(0), parser->issueCount()); + + importer->resolveImports(model, resourcePath("generator/cellml_slc_example")); + EXPECT_FALSE(model->hasUnresolvedImports()); + + auto flatModel = importer->flattenModel(model); + + auto printer = libcellml::Printer::create(); + EXPECT_EQ(e, printer->printModel(flatModel)); +} diff --git a/tests/resources/generator/cellml_slc_example/model.py b/tests/resources/generator/cellml_slc_example/model.py new file mode 100644 index 0000000000..65742c972a --- /dev/null +++ b/tests/resources/generator/cellml_slc_example/model.py @@ -0,0 +1,54 @@ +# The content of this file was generated using the Python profile of libCellML 0.5.0. + +from enum import Enum +from math import * + + +__version__ = "0.4.0" +LIBCELLML_VERSION = "0.5.0" + +VARIABLE_COUNT = 10 + + +class VariableType(Enum): + CONSTANT = 0 + COMPUTED_CONSTANT = 1 + ALGEBRAIC = 2 + + +VARIABLE_INFO = [ + {"name": "v", "units": "fmol_per_sec", "component": "SLC_template3_ss", "type": VariableType.COMPUTED_CONSTANT}, + {"name": "E", "units": "fmol", "component": "SLC_template3_ss", "type": VariableType.CONSTANT}, + {"name": "P_0", "units": "per_fmol_sec4", "component": "SLC_template3_ss", "type": VariableType.CONSTANT}, + {"name": "q_Ao", "units": "fmol", "component": "SLC_template3_ss", "type": VariableType.CONSTANT}, + {"name": "P_1", "units": "per_fmol_sec4", "component": "SLC_template3_ss", "type": VariableType.CONSTANT}, + {"name": "q_Ai", "units": "fmol", "component": "SLC_template3_ss", "type": VariableType.CONSTANT}, + {"name": "P_2", "units": "per_fmol_sec3", "component": "SLC_template3_ss", "type": VariableType.CONSTANT}, + {"name": "P_5", "units": "per_sec3", "component": "SLC_template3_ss", "type": VariableType.CONSTANT}, + {"name": "P_4", "units": "per_fmol2_sec3", "component": "SLC_template3_ss", "type": VariableType.CONSTANT}, + {"name": "P_3", "units": "per_fmol_sec3", "component": "SLC_template3_ss", "type": VariableType.CONSTANT} +] + + +def create_variables_array(): + return [nan]*VARIABLE_COUNT + + +def initialise_variables(variables): + variables[1] = 1.1 + variables[2] = 21262500.0 + variables[3] = 150.0 + variables[4] = 3402000.0 + variables[5] = 2.0 + variables[6] = 2902500.0 + variables[7] = 810000.0 + variables[8] = 247140.0 + variables[9] = 2902500.0 + + +def compute_computed_constants(variables): + variables[0] = variables[1]*(variables[2]*variables[3]-variables[4]*variables[5])/(variables[6]*variables[5]+variables[9]*variables[3]+variables[8]*variables[5]*variables[3]+variables[7]) + + +def compute_variables(variables): + pass diff --git a/tests/resources/generator/cellml_slc_example/slc_model.cellml b/tests/resources/generator/cellml_slc_example/slc_model.cellml new file mode 100644 index 0000000000..3dc06d1bce --- /dev/null +++ b/tests/resources/generator/cellml_slc_example/slc_model.cellml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + v + + + + + E + + + + + P_0 + q_Ao + + + + P_1 + q_Ai + + + + + + + + P_2 + q_Ai + + + + P_3 + q_Ao + + + + P_4 + q_Ai + q_Ao + + P_5 + + + + + + diff --git a/tests/resources/generator/cellml_slc_example/slc_model_units_only.cellml b/tests/resources/generator/cellml_slc_example/slc_model_units_only.cellml new file mode 100644 index 0000000000..5cd32894b3 --- /dev/null +++ b/tests/resources/generator/cellml_slc_example/slc_model_units_only.cellml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/tests/resources/generator/cellml_slc_example/units_BG.cellml b/tests/resources/generator/cellml_slc_example/units_BG.cellml new file mode 100644 index 0000000000..f36f0bca58 --- /dev/null +++ b/tests/resources/generator/cellml_slc_example/units_BG.cellml @@ -0,0 +1,221 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +