From 08dafcdb2f89dc161e19afc2f2232ad181252248 Mon Sep 17 00:00:00 2001 From: Alan Garny Date: Wed, 8 Apr 2026 23:50:13 +1200 Subject: [PATCH 01/12] Added a test for a very big CellML file. Note that the test is disabled since it performs repeated parse/analyse/generate loops, which take several minutes to complete. So, it should be enabled only when needed, and not as part of our regular test suite. --- tests/bindings/javascript/generator.test.js | 87 + tests/bindings/python/test_generator.py | 74 + tests/generator/generator.cpp | 73 + tests/resources/very_big_model.cellml | 43500 ++++++++++++++++++ 4 files changed, 43734 insertions(+) create mode 100644 tests/resources/very_big_model.cellml diff --git a/tests/bindings/javascript/generator.test.js b/tests/bindings/javascript/generator.test.js index 2c328e6ff..9ab593532 100644 --- a/tests/bindings/javascript/generator.test.js +++ b/tests/bindings/javascript/generator.test.js @@ -83,4 +83,91 @@ describe("Generator tests", () => { const equation_line_2 = libcellml.Generator.equationCodeByProfile(a.analyserModel().analyserEquation(0).ast(), gp) expect(equation_line_2.length).toBe(14) }) + /* + test('Very big model multiple times', () => { + const fs = require('fs') + const path = require('path') + + const issueFingerprint = (logger) => { + let fingerprint = '' + let issueCount = 0 + + const count = logger.issueCount() + for (let i = 0; i < count; ++i) { + const issue = logger.issue(i) + + ++issueCount + + fingerprint += `${issue.level()}|` + fingerprint += `${issue.referenceRule()}|` + fingerprint += `${issue.item().type()}|` + fingerprint += `${issue.url()}|` + fingerprint += `${issue.description()}\n` + } + + return `issues=${issueCount}\n${fingerprint}` + } + + const veryBigModel = fs.readFileSync(path.resolve(__dirname, "../../../../tests/resources/very_big_model.cellml"), "utf8") + + const parser = new libcellml.Parser(false) + const printer = new libcellml.Printer() + const analyser = new libcellml.Analyser() + const generator = new libcellml.Generator() + + let baselineParserFingerprint = '' + let baselinePrintedModel = '' + let baselineAnalyserFingerprint = '' + let baselineAnalyserModelType = libcellml.AnalyserModel.Type.UNKNOWN + let baselineInterfaceCode = '' + let baselineImplementationCode = '' + + for (let i = 0; i < 10; ++i) { + const model = parser.parseModel(veryBigModel) + + expect(model).not.toBeNull() + + const parserFingerprint = issueFingerprint(parser) + const printedModel = printer.printModel(model) + + analyser.analyseModel(model) + + const analyserFingerprint = issueFingerprint(analyser) + const analyserModel = analyser.analyserModel() + + expect(analyserModel).not.toBeNull() + + const interfaceCode = generator.interfaceCode(analyserModel) + const implementationCode = generator.implementationCode(analyserModel) + + if (i === 0) { + baselineParserFingerprint = parserFingerprint + baselinePrintedModel = printedModel + baselineAnalyserFingerprint = analyserFingerprint + baselineAnalyserModelType = analyserModel.type() + baselineInterfaceCode = interfaceCode + baselineImplementationCode = implementationCode + } else { + expect(parserFingerprint).toBe(baselineParserFingerprint) + expect(printedModel).toBe(baselinePrintedModel) + expect(analyserFingerprint).toBe(baselineAnalyserFingerprint) + expect(analyserModel.type()).toBe(baselineAnalyserModelType) + expect(interfaceCode).toBe(baselineInterfaceCode) + expect(implementationCode).toBe(baselineImplementationCode) + } + + // Clean up the model and analyser model before the next iteration. Indeed, if we don't do this, then we end + // up with 10 models and 10 analyser models in memory at the same time, which causes the test to run out of + // memory. + + analyserModel.delete() + model.delete() + } + + generator.delete() + analyser.delete() + printer.delete() + parser.delete() + }) + */ }) diff --git a/tests/bindings/python/test_generator.py b/tests/bindings/python/test_generator.py index e0aca348d..37d691835 100644 --- a/tests/bindings/python/test_generator.py +++ b/tests/bindings/python/test_generator.py @@ -52,6 +52,80 @@ def test_algebraic_eqn_computed_var_on_rhs(self): self.assertEqual("x = a", Generator.equationCode(am.analyserEquation(0).ast())) self.assertEqual("x = a", Generator_equationCode(am.analyserEquation(0).ast())) + """ + def test_very_big_model_multiple_times(self): + from libcellml import Analyser + from libcellml import AnalyserModel + from libcellml import Generator + from libcellml import Parser + from libcellml import Printer + from test_resources import file_contents + + def issue_fingerprint(logger): + fingerprint = '' + issue_count = 0 + + for i in range(logger.issueCount()): + issue = logger.issue(i) + + issue_count += 1 + + fingerprint += f"{issue.level()}|" + fingerprint += f"{issue.referenceRule()}|" + fingerprint += f"{issue.item().type()}|" + fingerprint += f"{issue.url()}|" + fingerprint += f"{issue.description()}\n" + + return f"issues={issue_count}\n{fingerprint}" + + very_big_model = file_contents('very_big_model.cellml') + + parser = Parser(False) + printer = Printer() + analyser = Analyser() + generator = Generator() + + baseline_parser_fingerprint = '' + baseline_printed_model = '' + baseline_analyser_fingerprint = '' + baseline_analyser_model_type = AnalyserModel.Type.UNKNOWN + baseline_interface_code = '' + baseline_implementation_code = '' + + for i in range(10): + model = parser.parseModel(very_big_model) + + self.assertIsNotNone(model) + + parser_fingerprint = issue_fingerprint(parser) + printed_model = printer.printModel(model) + + analyser.analyseModel(model) + + analyser_fingerprint = issue_fingerprint(analyser) + analyser_model = analyser.analyserModel() + + self.assertIsNotNone(analyser_model) + + interface_code = generator.interfaceCode(analyser_model) + implementation_code = generator.implementationCode(analyser_model) + + if i == 0: + baseline_parser_fingerprint = parser_fingerprint + baseline_printed_model = printed_model + baseline_analyser_fingerprint = analyser_fingerprint + baseline_analyser_model_type = analyser_model.type() + baseline_interface_code = interface_code + baseline_implementation_code = implementation_code + else: + self.assertEqual(baseline_parser_fingerprint, parser_fingerprint) + self.assertEqual(baseline_printed_model, printed_model) + self.assertEqual(baseline_analyser_fingerprint, analyser_fingerprint) + self.assertEqual(baseline_analyser_model_type, analyser_model.type()) + self.assertEqual(baseline_interface_code, interface_code) + self.assertEqual(baseline_implementation_code, implementation_code) + """ + if __name__ == '__main__': unittest.main() diff --git a/tests/generator/generator.cpp b/tests/generator/generator.cpp index 411080c52..069c6bfbb 100644 --- a/tests/generator/generator.cpp +++ b/tests/generator/generator.cpp @@ -1754,3 +1754,76 @@ TEST(Generator, generateCodeUsingProfileEnum) EXPECT_EQ_FILE_CONTENTS("generator/algebraic_eqn_computed_var_on_rhs/model.py", generator->implementationCode(analyserModel, libcellml::GeneratorProfile::Profile::PYTHON)); } + +/* +TEST(Generator, veryBigModelMultipleTimes) +{ + auto issueFingerprint = [](const libcellml::LoggerPtr &logger) { + std::string fingerprint; + size_t issueCount = 0; + + for (size_t i = 0; i < logger->issueCount(); ++i) { + const auto issue = logger->issue(i); + + ++issueCount; + + fingerprint += std::to_string(static_cast(issue->level())) + "|"; + fingerprint += std::to_string(static_cast(issue->referenceRule())) + "|"; + fingerprint += std::to_string(static_cast(issue->item()->type())) + "|"; + fingerprint += issue->url() + "|"; + fingerprint += issue->description() + "\n"; + } + + return "issues=" + std::to_string(issueCount) + "\n" + fingerprint; + }; + + auto veryBigModel = fileContents("very_big_model.cellml"); + + auto parser = libcellml::Parser::create(false); + auto printer = libcellml::Printer::create(); + auto analyser = libcellml::Analyser::create(); + auto generator = libcellml::Generator::create(); + + std::string baselineParserFingerprint; + std::string baselinePrintedModel; + std::string baselineAnalyserFingerprint; + auto baselineAnalyserModelType = libcellml::AnalyserModel::Type::UNKNOWN; + std::string baselineInterfaceCode; + std::string baselineImplementationCode; + + for (size_t i = 0; i < 10; ++i) { + auto model = parser->parseModel(veryBigModel); + + ASSERT_NE(nullptr, model); + + const auto parserFingerprint = issueFingerprint(parser); + const auto printedModel = printer->printModel(model); + + analyser->analyseModel(model); + + const auto analyserFingerprint = issueFingerprint(analyser); + const auto analyserModel = analyser->analyserModel(); + + ASSERT_NE(nullptr, analyserModel); + + const auto interfaceCode = generator->interfaceCode(analyserModel); + const auto implementationCode = generator->implementationCode(analyserModel); + + if (i == 0) { + baselineParserFingerprint = parserFingerprint; + baselinePrintedModel = printedModel; + baselineAnalyserFingerprint = analyserFingerprint; + baselineAnalyserModelType = analyserModel->type(); + baselineInterfaceCode = interfaceCode; + baselineImplementationCode = implementationCode; + } else { + EXPECT_EQ(baselineParserFingerprint, parserFingerprint); + EXPECT_EQ(baselinePrintedModel, printedModel); + EXPECT_EQ(baselineAnalyserFingerprint, analyserFingerprint); + EXPECT_EQ(baselineAnalyserModelType, analyserModel->type()); + EXPECT_EQ(baselineInterfaceCode, interfaceCode); + EXPECT_EQ(baselineImplementationCode, implementationCode); + } + } +} +*/ diff --git a/tests/resources/very_big_model.cellml b/tests/resources/very_big_model.cellml new file mode 100644 index 000000000..517eb82f4 --- /dev/null +++ b/tests/resources/very_big_model.cellml @@ -0,0 +1,43500 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + chi_afloor + + + chi_a + + + chi_a + + + + + + + + + t + + chi_a + + + + + + 0.25 + T_ac_wCont + + + + + + mt + t_astart_norm + + + + mt + + + t_astart_norm + eps_1 + + + + + chi_afloor + 0.25 + + + + + + + 0.25 + T_ac_wCont + + + + + + + + t_astart_norm + eps_1 + + 1.0 + + + + mt + + + + + t_astart_norm + eps_1 + + 1.0 + + + + + chi_afloor + 0.25 + + + + + + + 0.25 + T_ac_wCont + + + + + + chi_afloor + eps_2 + + + + chi_afloor + 0.25 + + + + + + + 0.25 + T_ar_wCont + + + + + + chi_afloor + 0.25 + + + + chi_afloor + 0.5 + + + + + + + 0.5 + + + + + T_wCont + T_ac_wCont + + T_ar_wCont + + + + + chi_afloor + 0.5 + + + + 0.0 + + + + + + chi_afloor_final + + + + + chi_afloor + 2 + + + + chi_afloor + 0.5 + + + + 0.0 + + + + + + + + chi_vfloor + + + chi_v + + + chi_v + + + + + + + + + t + + chi_v + + + + + + 0.25 + T_vc_wCont + + + + + + mt + t_vstart_norm + + + + mt + + + t_vstart_norm + eps_1 + + + + + chi_vfloor + 0.25 + + + + + + + 0.25 + T_vc_wCont + + + + + + + + t_vstart_norm + eps_1 + + 1.0 + + + + mt + + + + + t_vstart_norm + eps_1 + + 1.0 + + + + + chi_vfloor + 0.25 + + + + + + + 0.25 + T_vc_wCont + + + + + + chi_vfloor + eps_2 + + + + chi_vfloor + 0.25 + + + + + + + 0.25 + T_vr_wCont + + + + + + chi_vfloor + 0.25 + + + + chi_vfloor + 0.5 + + + + + + + 0.5 + + + + + T_wCont + T_vc_wCont + + T_vr_wCont + + + + + chi_vfloor + 0.5 + + + + 0.0 + + + + + + chi_vfloor_final + + + + + chi_vfloor + 2 + + + + chi_vfloor + 0.5 + + + + 0.0 + + + + + + + + + t + + s + + + + 1 + T_wCont + + + + + mt + + + s + + + s + + + + + + + + T_wCont + + + + + T + Delta_T + + T_min + + + + + T_ac_wCont + + + + + T_ac + T_wCont + + T + + + + + T_ar_wCont + + + + + T_ar + T_wCont + + T + + + + + T_vc_wCont + + + + + T_vc + T_wCont + + T + + + + + T_vr_wCont + + + + + T_vr + T_wCont + + T + + + + + + t_astart_norm + + + t_astart + T + + + + + + t_vstart_norm + + + t_vstart + T + + + + + + e_a + + + 0.5 + + + 1 + + + + + 2 + + chi_afloor_final + + + + + + + + e_v + + + 0.5 + + + 1 + + + + + 2 + + chi_vfloor_final + + + + + + + + + B_trv + + + rho + + + + + 2 + + + A_eff_trv + 2 + + + eps_m4 + + + + + + B_puv + + + rho + + + + + 2 + + + A_eff_puv + 2 + + + eps_m4 + + + + + + B_miv + + + rho + + + + + 2 + + + A_eff_miv + 2 + + + eps_m4 + + + + + + B_aov + + + rho + + + + + 2 + + + A_eff_aov + 2 + + + eps_m4 + + + + + + L_trv + + + + + rho + l_eff + + + + A_eff_trv + eps_m2 + + + + + + L_puv + + + + + rho + l_eff + + + + A_eff_puv + eps_m2 + + + + + + L_miv + + + + + rho + l_eff + + + + A_eff_miv + eps_m2 + + + + + + L_aov + + + + + rho + l_eff + + + + A_eff_aov + eps_m2 + + + + + + A_eff_trv + + + + + + + + + M_st_trv + A_nn_trv + + + + M_rg_trv + A_nn_trv + + + zeta_trv + + + + M_rg_trv + A_nn_trv + + + + + + A_eff_puv + + + + + + + + + M_st_puv + A_nn_puv + + + + M_rg_puv + A_nn_puv + + + zeta_puv + + + + M_rg_puv + A_nn_puv + + + + + + A_eff_miv + + + + + + + + + M_st_miv + A_nn_miv + + + + M_rg_miv + A_nn_miv + + + zeta_miv + + + + M_rg_miv + A_nn_miv + + + + + + A_eff_aov + + + + + + + + + M_st_aov + A_nn_aov + + + + M_rg_aov + A_nn_aov + + + zeta_aov + + + + M_rg_aov + A_nn_aov + + + + + + + + + t + + zeta_trv_pre + + + + + + + + 1 + zeta_trv_pre + + K_vo_trv + + + u_ra + u_rv + + + + + u_ra + u_rv + + + + + + zeta_trv_pre + K_vc_trv + + + u_ra + u_rv + + + + + + + + + + + t + + zeta_puv_pre + + + + + + + + 1 + zeta_puv_pre + + K_vo_puv + + + u_rv + u_par + + + + + u_rv + u_par + + + + + + zeta_puv_pre + K_vc_puv + + + u_rv + u_par + + + + + + + + + + + t + + zeta_miv_pre + + + + + + + + 1 + zeta_miv_pre + + K_vo_miv + + + u_la + u_lv + + + + + u_la + u_lv + + + + + + zeta_miv_pre + K_vc_miv + + + u_la + u_lv + + + + + + + + + + + t + + zeta_aov_pre + + + + + + + + 1 + zeta_aov_pre + + K_vo_aov + + + u_lv + u_root + + + + + u_lv + u_root + + + + + + zeta_aov_pre + K_vc_aov + + + u_lv + u_root + + + + + + + + + zeta_trv + + + zeta_trv_pre + 0 + + + + + zeta_puv + + + zeta_puv_pre + 0 + + + + + zeta_miv + + + zeta_miv_pre + 0 + + + + + zeta_aov + + + zeta_aov_pre + 0 + + + + + + + + + t + + v_trv + + + + + + + + + + + + B_trv + + v_trv + + + v_trv + + + u_ra + + u_rv + + L_trv + + + + + + + + t + + v_puv + + + + + + + + + + + + B_puv + + v_puv + + + v_puv + + + u_rv + + u_par + + L_puv + + + + + + + + t + + v_miv + + + + + + + + + + + + B_miv + + v_miv + + + v_miv + + + u_la + + u_lv + + L_miv + + + + + + + + t + + v_aov + + + + + + + + + + + + B_aov + + v_aov + + + v_aov + + + u_lv + + u_root + + L_aov + + + + + + + E_rv_A_wCont + + + E_rv_A + Delta_E_rv + + + + + E_lv_A_wCont + + + E_lv_A + Delta_E_lv + + + + + + u_ra + + + + + + + e_a + E_ra_A + + E_ra_B + + + + q_ra + q_ra_us + + + + + + u_rv + + + + + + + e_v + E_rv_A_wCont + + E_rv_B + + + + q_rv + q_rv_us + + + + + + u_la + + + + + + + e_a + E_la_A + + E_la_B + + + + q_la + q_la_us + + + + + + u_lv + + + + + + + e_v + E_lv_A_wCont + + E_lv_B + + + + q_lv + q_lv_us + + + + + + + + + + t + + q_ra + + + + + + v_svc + v_ivc + + v_trv + + + + + + + + t + + q_rv + + + + v_trv + v_puv + + + + + + + + t + + q_la + + + + v_pvn + v_miv + + + + + + + + t + + q_lv + + + + v_miv + v_aov + + + + + + + q_heart + + + q_ra + q_rv + q_la + q_lv + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_C_d + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u + u_d + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v_in + v + + + + + u_C + + + q_C + + + C + 2 + + + + + + + + + t + + q_C_d + + + + + + v + v_out_1 + + v_out_2 + + + + + u_C_d + + + q_C_d + + + C + 2 + + + + + + u + + + u_0 + u_C + u_ext + + + 2 + R_v + + + v_in + v + + + + + + + u_d + + + u_0 + u_C_d + u_ext + + + 2 + R_v + + + + + v + v_out_1 + + v_out_2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + du_C_dt + + + + + + + v + v_out_1 + + v_out_2 + + C + + + + + + + + + t + + q_C + + + + + + v + v_out_1 + + v_out_2 + + + + + u_C + + + + + q_C + C + + u_ext + + + + + u + + + u_0 + u_C + + + R_v + + + + + v + v_out_1 + + v_out_2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + du_C_dt + + + + + + + v + v_out_1 + + v_out_2 + + C + + + + + + + + + t + + q_C + + + + + + v + v_out_1 + + v_out_2 + + + + + u_C + + + + + q_C + C + + u_ext + + + + + u + + + u_0 + u_C + + + R_v + + + + + v + v_out_1 + + v_out_2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + du_C_dt + + + + + + + v + v_out_1 + + v_out_2 + + C + + + + + + + + + t + + q_C + + + + + + v + v_out_1 + + v_out_2 + + + + + u_C + + + + + q_C + C + + u_ext + + + + + u + + + u_0 + u_C + + + R_v + + + + + v + v_out_1 + + v_out_2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + du_C_dt + + + + + + + v + v_out_1 + + v_out_2 + + C + + + + + + + + + t + + q_C + + + + + + v + v_out_1 + + v_out_2 + + + + + u_C + + + + + q_C + C + + u_ext + + + + + u + + + u_0 + u_C + + + R_v + + + + + v + v_out_1 + + v_out_2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + du_C_dt + + + + + + + v + v_out_1 + + v_out_2 + + C + + + + + + + + + t + + q_C + + + + + + v + v_out_1 + + v_out_2 + + + + + u_C + + + + + q_C + C + + u_ext + + + + + u + + + u_0 + u_C + + + R_v + + + + + v + v_out_1 + + v_out_2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + du_C_dt + + + + + + + v + v_out_1 + + v_out_2 + + C + + + + + + + + + t + + q_C + + + + + + v + v_out_1 + + v_out_2 + + + + + u_C + + + + + q_C + C + + u_ext + + + + + u + + + u_0 + u_C + + + R_v + + + + + v + v_out_1 + + v_out_2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + du_C_dt + + + + + + + v + v_out_1 + + v_out_2 + + C + + + + + + + + + t + + q_C + + + + + + v + v_out_1 + + v_out_2 + + + + + u_C + + + + + q_C + C + + u_ext + + + + + u + + + u_0 + u_C + + + R_v + + + + + v + v_out_1 + + v_out_2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + du_C_dt + + + + + + + v + v_out_1 + + v_out_2 + + C + + + + + + + + + t + + q_C + + + + + + v + v_out_1 + + v_out_2 + + + + + u_C + + + + + q_C + C + + u_ext + + + + + u + + + u_0 + u_C + + + R_v + + + + + v + v_out_1 + + v_out_2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + du_C_dt + + + + + + + v + v_out_1 + + v_out_2 + + C + + + + + + + + + t + + q_C + + + + + + v + v_out_1 + + v_out_2 + + + + + u_C + + + + + q_C + C + + u_ext + + + + + u + + + u_0 + u_C + + + R_v + + + + + v + v_out_1 + + v_out_2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + du_C_dt + + + + + + + v + v_out_1 + + v_out_2 + + C + + + + + + + + + t + + q_C + + + + + + v + v_out_1 + + v_out_2 + + + + + u_C + + + + + q_C + C + + u_ext + + + + + u + + + u_0 + u_C + + + R_v + + + + + v + v_out_1 + + v_out_2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + du_C_dt + + + + + + + v + v_out_1 + + v_out_2 + + C + + + + + + + + + t + + q_C + + + + + + v + v_out_1 + + v_out_2 + + + + + u_C + + + + + q_C + C + + u_ext + + + + + u + + + u_0 + u_C + + + R_v + + + + + v + v_out_1 + + v_out_2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + du_C_dt + + + + + + + v + v_out_1 + + v_out_2 + + C + + + + + + + + + t + + q_C + + + + + + v + v_out_1 + + v_out_2 + + + + + u_C + + + + + q_C + C + + u_ext + + + + + u + + + u_0 + u_C + + + R_v + + + + + v + v_out_1 + + v_out_2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + du_C_dt + + + + + + + v + v_out_1 + + v_out_2 + + C + + + + + + + + + t + + q_C + + + + + + v + v_out_1 + + v_out_2 + + + + + u_C + + + + + q_C + C + + u_ext + + + + + u + + + u_0 + u_C + + + R_v + + + + + v + v_out_1 + + v_out_2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + du_C_dt + + + + + + + v + v_out_1 + + v_out_2 + + C + + + + + + + + + t + + q_C + + + + + + v + v_out_1 + + v_out_2 + + + + + u_C + + + + + q_C + C + + u_ext + + + + + u + + + u_0 + u_C + + + R_v + + + + + v + v_out_1 + + v_out_2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + du_C_dt + + + + + + + v + v_out_1 + + v_out_2 + + C + + + + + + + + + t + + q_C + + + + + + v + v_out_1 + + v_out_2 + + + + + u_C + + + + + q_C + C + + u_ext + + + + + u + + + u_0 + u_C + + + R_v + + + + + v + v_out_1 + + v_out_2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + du_C_dt + + + + + + + v + v_out_1 + + v_out_2 + + C + + + + + + + + + t + + q_C + + + + + + v + v_out_1 + + v_out_2 + + + + + u_C + + + + + q_C + C + + u_ext + + + + + u + + + u_0 + u_C + + + R_v + + + + + v + v_out_1 + + v_out_2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + du_C_dt + + + + + + + v + v_out_1 + + v_out_2 + + C + + + + + + + + + t + + q_C + + + + + + v + v_out_1 + + v_out_2 + + + + + u_C + + + + + q_C + C + + u_ext + + + + + u + + + u_0 + u_C + + + R_v + + + + + v + v_out_1 + + v_out_2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + du_C_dt + + + + + + + v + v_out_1 + + v_out_2 + + C + + + + + + + + + t + + q_C + + + + + + v + v_out_1 + + v_out_2 + + + + + u_C + + + + + q_C + C + + u_ext + + + + + u + + + u_0 + u_C + + + R_v + + + + + v + v_out_1 + + v_out_2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + du_C_dt + + + + + + + v + v_out_1 + + v_out_2 + + C + + + + + + + + + t + + q_C + + + + + + v + v_out_1 + + v_out_2 + + + + + u_C + + + + + q_C + C + + u_ext + + + + + u + + + u_0 + u_C + + + R_v + + + + + v + v_out_1 + + v_out_2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + du_C_dt + + + + + + + v + v_out_1 + + v_out_2 + + C + + + + + + + + + t + + q_C + + + + + + v + v_out_1 + + v_out_2 + + + + + u_C + + + + + q_C + C + + u_ext + + + + + u + + + u_0 + u_C + + + R_v + + + + + v + v_out_1 + + v_out_2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + du_C_dt + + + + + + + v + v_out_1 + + v_out_2 + + C + + + + + + + + + t + + q_C + + + + + + v + v_out_1 + + v_out_2 + + + + + u_C + + + + + q_C + C + + u_ext + + + + + u + + + u_0 + u_C + + + R_v + + + + + v + v_out_1 + + v_out_2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + du_C_dt + + + + + + + v + v_out_1 + + v_out_2 + + C + + + + + + + + + t + + q_C + + + + + + v + v_out_1 + + v_out_2 + + + + + u_C + + + + + q_C + C + + u_ext + + + + + u + + + u_0 + u_C + + + R_v + + + + + v + v_out_1 + + v_out_2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + du_C_dt + + + + + + + v + v_out_1 + + v_out_2 + + C + + + + + + + + + t + + q_C + + + + + + v + v_out_1 + + v_out_2 + + + + + u_C + + + + + q_C + C + + u_ext + + + + + u + + + u_0 + u_C + + + R_v + + + + + v + v_out_1 + + v_out_2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + du_C_dt + + + + + + + v + v_out_1 + + v_out_2 + + C + + + + + + + + + t + + q_C + + + + + + v + v_out_1 + + v_out_2 + + + + + u_C + + + + + q_C + C + + u_ext + + + + + u + + + u_0 + u_C + + + R_v + + + + + v + v_out_1 + + v_out_2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + du_C_dt + + + + + + + v + v_out_1 + + v_out_2 + + C + + + + + + + + + t + + q_C + + + + + + v + v_out_1 + + v_out_2 + + + + + u_C + + + + + q_C + C + + u_ext + + + + + u + + + u_0 + u_C + + + R_v + + + + + v + v_out_1 + + v_out_2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + du_C_dt + + + + + + + v + v_out_1 + + v_out_2 + + C + + + + + + + + + t + + q_C + + + + + + v + v_out_1 + + v_out_2 + + + + + u_C + + + + + q_C + C + + u_ext + + + + + u + + + u_0 + u_C + + + R_v + + + + + v + v_out_1 + + v_out_2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + du_C_dt + + + + + + + v + v_out_1 + + v_out_2 + + C + + + + + + + + + t + + q_C + + + + + + v + v_out_1 + + v_out_2 + + + + + u_C + + + + + q_C + C + + u_ext + + + + + u + + + u_0 + u_C + + + R_v + + + + + v + v_out_1 + + v_out_2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + + + R + 2 + + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + + + I + 2 + + + + + + + + + t + + q_C + + + + v + v_d + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_d + + + + + + + + + + t + + v_d + + + + + + + + u + u_out + + + + + + R + 2 + + v_d + + + + + I + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + + + R + 2 + + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + + + I + 2 + + + + + + + + + t + + q_C + + + + v + v_d + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_d + + + + + + + + + + t + + v_d + + + + + + + + u + u_out + + + + + + R + 2 + + v_d + + + + + I + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_C_d + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u + u_d + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + + + v_in_1 + v_in_2 + + v + + + + + u_C + + + q_C + + + C + 2 + + + + + + + + + t + + q_C_d + + + + + + v + v_out_1 + + v_out_2 + + + + + u_C_d + + + q_C_d + + + C + 2 + + + + + + u + + + u_0 + u_ext + u_C + + + 2 + R_v + + + + + v_in_1 + v_in_2 + + v + + + + + + + u_d + + + u_0 + u_ext + u_C_d + + + 2 + R_v + + + + + v + v_out_1 + + v_out_2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + du_C_dt + + + + + + + v + v_out_1 + + v_out_2 + + C + + + + + + + + + t + + q_C + + + + + + v + v_out_1 + + v_out_2 + + + + + u_C + + + + + q_C + C + + u_ext + + + + + u + + + u_0 + u_C + + + R_v + + + + + v + v_out_1 + + v_out_2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + du_C_dt + + + + + + + v + v_out_1 + + v_out_2 + + C + + + + + + + + + t + + q_C + + + + + + v + v_out_1 + + v_out_2 + + + + + u_C + + + + + q_C + C + + u_ext + + + + + u + + + u_0 + u_C + + + R_v + + + + + v + v_out_1 + + v_out_2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + du_C_dt + + + + + + + v + v_out_1 + + v_out_2 + + C + + + + + + + + + t + + q_C + + + + + + v + v_out_1 + + v_out_2 + + + + + u_C + + + + + q_C + C + + u_ext + + + + + u + + + u_0 + u_C + + + R_v + + + + + v + v_out_1 + + v_out_2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + du_C_dt + + + + + + + v + v_out_1 + + v_out_2 + + C + + + + + + + + + t + + q_C + + + + + + v + v_out_1 + + v_out_2 + + + + + u_C + + + + + q_C + C + + u_ext + + + + + u + + + u_0 + u_C + + + R_v + + + + + v + v_out_1 + + v_out_2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + du_C_dt + + + + + + + v + v_out_1 + + v_out_2 + + C + + + + + + + + + t + + q_C + + + + + + v + v_out_1 + + v_out_2 + + + + + u_C + + + + + q_C + C + + u_ext + + + + + u + + + u_0 + u_C + + + R_v + + + + + v + v_out_1 + + v_out_2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + du_C_dt + + + + + + + v + v_out_1 + + v_out_2 + + C + + + + + + + + + t + + q_C + + + + + + v + v_out_1 + + v_out_2 + + + + + u_C + + + + + q_C + C + + u_ext + + + + + u + + + u_0 + u_C + + + R_v + + + + + v + v_out_1 + + v_out_2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + du_C_dt + + + + + + + v + v_out_1 + + v_out_2 + + C + + + + + + + + + t + + q_C + + + + + + v + v_out_1 + + v_out_2 + + + + + u_C + + + + + q_C + C + + u_ext + + + + + u + + + u_0 + u_C + + + R_v + + + + + v + v_out_1 + + v_out_2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + + + R + 2 + + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + + + I + 2 + + + + + + + + + t + + q_C + + + + v + v_d + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_d + + + + + + + + + + t + + v_d + + + + + + + + u + u_out + + + + + + R + 2 + + v_d + + + + + I + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + du_C_dt + + + + + + + v + v_out_1 + + v_out_2 + + C + + + + + + + + + t + + q_C + + + + + + v + v_out_1 + + v_out_2 + + + + + u_C + + + + + q_C + C + + u_ext + + + + + u + + + u_0 + u_C + + + R_v + + + + + v + v_out_1 + + v_out_2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + du_C_dt + + + + + + + v + v_out_1 + + v_out_2 + + C + + + + + + + + + t + + q_C + + + + + + v + v_out_1 + + v_out_2 + + + + + u_C + + + + + q_C + C + + u_ext + + + + + u + + + u_0 + u_C + + + R_v + + + + + v + v_out_1 + + v_out_2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + + + R + 2 + + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + + + I + 2 + + + + + + + + + t + + q_C + + + + v + v_d + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_d + + + + + + + + + + t + + v_d + + + + + + + + u + u_out + + + + + + R + 2 + + v_d + + + + + I + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u + u_out + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + + + v_in_1 + v_in_2 + + v + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_ext + u_C + + + R_v + + + + + v_in_1 + v_in_2 + + v + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_C_d + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u + u_d + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + + + v_in_1 + v_in_2 + + v + + + + + u_C + + + q_C + + + C + 2 + + + + + + + + + t + + q_C_d + + + + v + v_out + + + + + u_C_d + + + q_C_d + + + C + 2 + + + + + + u + + + u_0 + u_ext + u_C + + + 2 + R_v + + + + + v_in_1 + v_in_2 + + v + + + + + + + u_d + + + u_0 + u_ext + u_C_d + + + 2 + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + + + R + 2 + + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + + + I + 2 + + + + + + + + + t + + q_C + + + + v + v_d + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_d + + + + + + + + + + t + + v_d + + + + + + + + u + u_out + + + + + + R + 2 + + v_d + + + + + I + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + + + R + 2 + + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + + + I + 2 + + + + + + + + + t + + q_C + + + + v + v_d + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_d + + + + + + + + + + t + + v_d + + + + + + + + u + u_out + + + + + + R + 2 + + v_d + + + + + I + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_C_d + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u + u_d + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + + + v_in_1 + v_in_2 + + v + + + + + u_C + + + q_C + + + C + 2 + + + + + + + + + t + + q_C_d + + + + v + v_out + + + + + u_C_d + + + q_C_d + + + C + 2 + + + + + + u + + + u_0 + u_ext + u_C + + + 2 + R_v + + + + + v_in_1 + v_in_2 + + v + + + + + + + u_d + + + u_0 + u_ext + u_C_d + + + 2 + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + + + R + 2 + + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + + + I + 2 + + + + + + + + + t + + q_C + + + + v + v_d + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_d + + + + + + + + + + t + + v_d + + + + + + + + u + u_out + + + + + + R + 2 + + v_d + + + + + I + 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q_0 + + + + + + r_0 + 2 + + l + + + + + q + + + q_C + q_0 + + + + + + h + + + r_0 + + + + + a_vessel + + + + + b_vessel + r_0 + + + + + + c_vessel + + + + + d_vessel + r_0 + + + + + + + + + I + + + + + rho + l + + + + + + + r_0 + 2 + + + + + + + C + + + + + 2 + + + + r_0 + 3 + + l + + + + E + h + + + + + + R + + + + + 8 + mu + l + + + + + + + r_0 + 4 + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + + + u_in + u + + + + R + v + + + + + beta_g + rho + g + l + + + + + + + theta + + + 180 + + + + + I + + + + + + + + t + + q_C + + + + v + v_out + + + + + u_C + + + q_C + C + + + + + u + + + u_0 + u_C + u_ext + + + R_v + + + v + v_out + + + + + + + + + + + + + + + + + + + + + + + + + + + + + R_v + + + 0.01 + C_T + + + + + + + + + + t + + q + + + + v + v_T + + + + + u_C + + + + + + + q + q_us + + C_T + + u_ext + + + + + u + + + u_C + + + R_v + + + v + v_T + + + + + + + + + + t + + v + + + + + + + + u_in + u + + + + + + v + R_T_wCont + + 2 + + + I_T + + + + + + + + t + + v_T + + + + + + + + u + u_out + + + + + + v_T + R_T_wCont + + 2 + + + I_T + + + + + R_T_wCont + + + + + R_T + Delta_R + + R_local_multiplier + + + + + + + + + + + + + + + + + + + + + + + + + + + R_v + + + 0.01 + C_T + + + + + + + + + + t + + q + + + + v + v_T + + + + + u_C + + + + + + + q + q_us + + C_T + + u_ext + + + + + u + + + u_C + + + R_v + + + v + v_T + + + + + + + + + + t + + v + + + + + + + + u_in + u + + + + + + v + R_T_wCont + + 2 + + + I_T + + + + + + + + t + + v_T + + + + + + + + u + u_out + + + + + + v_T + R_T_wCont + + 2 + + + I_T + + + + + R_T_wCont + + + + + R_T + Delta_R + + R_local_multiplier + + + + + + + + + + + + + + + + + + + + + + + + + + + R_v + + + 0.01 + C_T + + + + + + + + + + t + + q + + + + v + v_T + + + + + u_C + + + + + + + q + q_us + + C_T + + u_ext + + + + + u + + + u_C + + + R_v + + + v + v_T + + + + + + + + + + t + + v + + + + + + + + u_in + u + + + + + + v + R_T_wCont + + 2 + + + I_T + + + + + + + + t + + v_T + + + + + + + + u + u_out + + + + + + v_T + R_T_wCont + + 2 + + + I_T + + + + + R_T_wCont + + + + + R_T + Delta_R + + R_local_multiplier + + + + + + + + + + + + + + + + + + + + + + + + + + + R_v + + + 0.01 + C_T + + + + + + + + + + t + + q + + + + v + v_T + + + + + u_C + + + + + + + q + q_us + + C_T + + u_ext + + + + + u + + + u_C + + + R_v + + + v + v_T + + + + + + + + + + t + + v + + + + + + + + u_in + u + + + + + + v + R_T_wCont + + 2 + + + I_T + + + + + + + + t + + v_T + + + + + + + + u + u_out + + + + + + v_T + R_T_wCont + + 2 + + + I_T + + + + + R_T_wCont + + + + + R_T + Delta_R + + R_local_multiplier + + + + + + + + + + + + + + + + + + + + + + + + + + + R_v + + + 0.01 + C_T + + + + + + + + + + t + + q + + + + v + v_T + + + + + u_C + + + + + + + q + q_us + + C_T + + u_ext + + + + + u + + + u_C + + + R_v + + + v + v_T + + + + + + + + + + t + + v + + + + + + + + u_in + u + + + + + + v + R_T_wCont + + 2 + + + I_T + + + + + + + + t + + v_T + + + + + + + + u + u_out + + + + + + v_T + R_T_wCont + + 2 + + + I_T + + + + + R_T_wCont + + + + + R_T + Delta_R + + R_local_multiplier + + + + + + + + + + + + + + + + + + + + + + + + + + + R_v + + + 0.01 + C_T + + + + + + + + + + t + + q + + + + v + v_T + + + + + u_C + + + + + + + q + q_us + + C_T + + u_ext + + + + + u + + + u_C + + + R_v + + + v + v_T + + + + + + + + + + t + + v + + + + + + + + u_in + u + + + + + + v + R_T_wCont + + 2 + + + I_T + + + + + + + + t + + v_T + + + + + + + + u + u_out + + + + + + v_T + R_T_wCont + + 2 + + + I_T + + + + + R_T_wCont + + + + + R_T + Delta_R + + R_local_multiplier + + + + + + + + + + + + + + + + + + + + + + + + + + + R_v + + + 0.01 + C_T + + + + + + + + + + t + + q + + + + v + v_T + + + + + u_C + + + + + + + q + q_us + + C_T + + u_ext + + + + + u + + + u_C + + + R_v + + + v + v_T + + + + + + + + + + t + + v + + + + + + + + u_in + u + + + + + + v + R_T_wCont + + 2 + + + I_T + + + + + + + + t + + v_T + + + + + + + + u + u_out + + + + + + v_T + R_T_wCont + + 2 + + + I_T + + + + + R_T_wCont + + + + + R_T + Delta_R + + R_local_multiplier + + + + + + + + + + + + + + + + + + + + + + + + + + + R_v + + + 0.01 + C_T + + + + + + + + + + t + + q + + + + v + v_T + + + + + u_C + + + + + + + q + q_us + + C_T + + u_ext + + + + + u + + + u_C + + + R_v + + + v + v_T + + + + + + + + + + t + + v + + + + + + + + u_in + u + + + + + + v + R_T_wCont + + 2 + + + I_T + + + + + + + + t + + v_T + + + + + + + + u + u_out + + + + + + v_T + R_T_wCont + + 2 + + + I_T + + + + + R_T_wCont + + + + + R_T + Delta_R + + R_local_multiplier + + + + + + + + + + + + + + + + + + + + + + + + + + + R_v + + + 0.01 + C_T + + + + + + + + + + t + + q + + + + v + v_T + + + + + u_C + + + + + + + q + q_us + + C_T + + u_ext + + + + + u + + + u_C + + + R_v + + + v + v_T + + + + + + + + + + t + + v + + + + + + + + u_in + u + + + + + + v + R_T_wCont + + 2 + + + I_T + + + + + + + + t + + v_T + + + + + + + + u + u_out + + + + + + v_T + R_T_wCont + + 2 + + + I_T + + + + + R_T_wCont + + + + + R_T + Delta_R + + R_local_multiplier + + + + + + + + + + + + + + + + + + + + + + + + + + + R_v + + + 0.01 + C_T + + + + + + + + + + t + + q + + + + v + v_T + + + + + u_C + + + + + + + q + q_us + + C_T + + u_ext + + + + + u + + + u_C + + + R_v + + + v + v_T + + + + + + + + + + t + + v + + + + + + + + u_in + u + + + + + + v + R_T_wCont + + 2 + + + I_T + + + + + + + + t + + v_T + + + + + + + + u + u_out + + + + + + v_T + R_T_wCont + + 2 + + + I_T + + + + + R_T_wCont + + + + + R_T + Delta_R + + R_local_multiplier + + + + + + + + + + + + + + + + + + + + + + + + + + + R_v + + + 0.01 + C_T + + + + + + + + + + t + + q + + + + v + v_T + + + + + u_C + + + + + + + q + q_us + + C_T + + u_ext + + + + + u + + + u_C + + + R_v + + + v + v_T + + + + + + + + + + t + + v + + + + + + + + u_in + u + + + + + + v + R_T_wCont + + 2 + + + I_T + + + + + + + + t + + v_T + + + + + + + + u + u_out + + + + + + v_T + R_T_wCont + + 2 + + + I_T + + + + + R_T_wCont + + + + + R_T + Delta_R + + R_local_multiplier + + + + + + + + + + + + + + + + + + + + + + + + + + + R_v + + + 0.01 + C_T + + + + + + + + + + t + + q + + + + v + v_T + + + + + u_C + + + + + + + q + q_us + + C_T + + u_ext + + + + + u + + + u_C + + + R_v + + + v + v_T + + + + + + + + + + t + + v + + + + + + + + u_in + u + + + + + + v + R_T_wCont + + 2 + + + I_T + + + + + + + + t + + v_T + + + + + + + + u + u_out + + + + + + v_T + R_T_wCont + + 2 + + + I_T + + + + + R_T_wCont + + + + + R_T + Delta_R + + R_local_multiplier + + + + + + + + + + + + + + + + + + + + + + + + + + + R_v + + + 0.01 + C_T + + + + + + + + + + t + + q + + + + v + v_T + + + + + u_C + + + + + + + q + q_us + + C_T + + u_ext + + + + + u + + + u_C + + + R_v + + + v + v_T + + + + + + + + + + t + + v + + + + + + + + u_in + u + + + + + + v + R_T_wCont + + 2 + + + I_T + + + + + + + + t + + v_T + + + + + + + + u + u_out + + + + + + v_T + R_T_wCont + + 2 + + + I_T + + + + + R_T_wCont + + + + + R_T + Delta_R + + R_local_multiplier + + + + + + + + + + + + + + + + + + + + + + + + + + + R_v + + + 0.01 + C_T + + + + + + + + + + t + + q + + + + v + v_T + + + + + u_C + + + + + + + q + q_us + + C_T + + u_ext + + + + + u + + + u_C + + + R_v + + + v + v_T + + + + + + + + + + t + + v + + + + + + + + u_in + u + + + + + + v + R_T_wCont + + 2 + + + I_T + + + + + + + + t + + v_T + + + + + + + + u + u_out + + + + + + v_T + R_T_wCont + + 2 + + + I_T + + + + + R_T_wCont + + + + + R_T + Delta_R + + R_local_multiplier + + + + + + + + + + + + + + + + + + + + + + + + + + + R_v + + + 0.01 + C_T + + + + + + + + + + t + + q + + + + v + v_T + + + + + u_C + + + + + + + q + q_us + + C_T + + u_ext + + + + + u + + + u_C + + + R_v + + + v + v_T + + + + + + + + + + t + + v + + + + + + + + u_in + u + + + + + + v + R_T_wCont + + 2 + + + I_T + + + + + + + + t + + v_T + + + + + + + + u + u_out + + + + + + v_T + R_T_wCont + + 2 + + + I_T + + + + + R_T_wCont + + + + + R_T + Delta_R + + R_local_multiplier + + + + + + + + + + + + + + + + + + + + + + + + + + + R_v + + + 0.01 + C_T + + + + + + + + + + t + + q + + + + v + v_T + + + + + u_C + + + + + + + q + q_us + + C_T + + u_ext + + + + + u + + + u_C + + + R_v + + + v + v_T + + + + + + + + + + t + + v + + + + + + + + u_in + u + + + + + + v + R_T_wCont + + 2 + + + I_T + + + + + + + + t + + v_T + + + + + + + + u + u_out + + + + + + v_T + R_T_wCont + + 2 + + + I_T + + + + + R_T_wCont + + + + + R_T + Delta_R + + R_local_multiplier + + + + + + + + + + + + + + + + + + + + + + + + + + + R_v + + + 0.01 + C_T + + + + + + + + + + t + + q + + + + v + v_T + + + + + u_C + + + + + + + q + q_us + + C_T + + u_ext + + + + + u + + + u_C + + + R_v + + + v + v_T + + + + + + + + + + t + + v + + + + + + + + u_in + u + + + + + + v + R_T_wCont + + 2 + + + I_T + + + + + + + + t + + v_T + + + + + + + + u + u_out + + + + + + v_T + R_T_wCont + + 2 + + + I_T + + + + + R_T_wCont + + + + + R_T + Delta_R + + R_local_multiplier + + + + + + + + + + + + + + + + + + + + + + + + + + + R_v + + + 0.01 + C_T + + + + + + + + + + t + + q + + + + v + v_T + + + + + u_C + + + + + + + q + q_us + + C_T + + u_ext + + + + + u + + + u_C + + + R_v + + + v + v_T + + + + + + + + + + t + + v + + + + + + + + u_in + u + + + + + + v + R_T_wCont + + 2 + + + I_T + + + + + + + + t + + v_T + + + + + + + + u + u_out + + + + + + v_T + R_T_wCont + + 2 + + + I_T + + + + + R_T_wCont + + + + + R_T + Delta_R + + R_local_multiplier + + + + + + + + + + + + + + + + + + + + + + + + + + + R_v + + + 0.01 + C_T + + + + + + + + + + t + + q + + + + v + v_T + + + + + u_C + + + + + + + q + q_us + + C_T + + u_ext + + + + + u + + + u_C + + + R_v + + + v + v_T + + + + + + + + + + t + + v + + + + + + + + u_in + u + + + + + + v + R_T_wCont + + 2 + + + I_T + + + + + + + + t + + v_T + + + + + + + + u + u_out + + + + + + v_T + R_T_wCont + + 2 + + + I_T + + + + + R_T_wCont + + + + + R_T + Delta_R + + R_local_multiplier + + + + + + + + + + + + + + + + + + + + + + + + + + + R_v + + + 0.01 + C_T + + + + + + + + + + t + + q + + + + v + v_T + + + + + u_C + + + + + + + q + q_us + + C_T + + u_ext + + + + + u + + + u_C + + + R_v + + + v + v_T + + + + + + + + + + t + + v + + + + + + + + u_in + u + + + + + + v + R_T_wCont + + 2 + + + I_T + + + + + + + + t + + v_T + + + + + + + + u + u_out + + + + + + v_T + R_T_wCont + + 2 + + + I_T + + + + + R_T_wCont + + + + + R_T + Delta_R + + R_local_multiplier + + + + + + + + + + + + + + + + + + + + + + + + + + + R_v + + + 0.01 + C_T + + + + + + + + + + t + + q + + + + v + v_T + + + + + u_C + + + + + + + q + q_us + + C_T + + u_ext + + + + + u + + + u_C + + + R_v + + + v + v_T + + + + + + + + + + t + + v + + + + + + + + u_in + u + + + + + + v + R_T_wCont + + 2 + + + I_T + + + + + + + + t + + v_T + + + + + + + + u + u_out + + + + + + v_T + R_T_wCont + + 2 + + + I_T + + + + + R_T_wCont + + + + + R_T + Delta_R + + R_local_multiplier + + + + + + + + + + + + + + + + + + + + + + + + R_v + + + 0.01 + C_T + + + + + I_T + 1-6 + + + + + + + + + t + + q + + + + v + v_T + + + + + u_C + + + + + q + q_us + + C_T + + + + + + u + + + u_C + u_ext + + + R_v + + + v + v_T + + + + + + + + + + t + + v + + + + + + + + u_in + u + + + + + + v + R_T + + 2 + + + I_T + + + + + + + + t + + v_T + + + + + + + + u + u_out + + + + + + v_T + R_T + + 2 + + + I_T + + + + + + + + + + + + + + + + + + + + + + + + R_v + + + 0.01 + C_T + + + + + I_T + 1-6 + + + + + + + + + t + + q + + + + v + v_T + + + + + u_C + + + + + q + q_us + + C_T + + + + + + u + + + u_C + u_ext + + + R_v + + + v + v_T + + + + + + + + + + t + + v + + + + + + + + u_in + u + + + + + + v + R_T + + 2 + + + I_T + + + + + + + + t + + v_T + + + + + + + + u + u_out + + + + + + v_T + R_T + + 2 + + + I_T + + + + + + + + + + + + + + + + + + + + + + + + R_v + + + 0.01 + C_T + + + + + I_T + 1-6 + + + + + + + + + t + + q + + + + v + v_T + + + + + u_C + + + + + q + q_us + + C_T + + + + + + u + + + u_C + u_ext + + + R_v + + + v + v_T + + + + + + + + + + t + + v + + + + + + + + u_in + u + + + + + + v + R_T + + 2 + + + I_T + + + + + + + + t + + v_T + + + + + + + + u + u_out + + + + + + v_T + R_T + + 2 + + + I_T + + + + + + + + + + + + + + + + + + + + + + + + R_v + + + 0.01 + C_T + + + + + I_T + 1-6 + + + + + + + + + t + + q + + + + v + v_T + + + + + u_C + + + + + q + q_us + + C_T + + + + + + u + + + u_C + u_ext + + + R_v + + + v + v_T + + + + + + + + + + t + + v + + + + + + + + u_in + u + + + + + + v + R_T + + 2 + + + I_T + + + + + + + + t + + v_T + + + + + + + + u + u_out + + + + + + v_T + R_T + + 2 + + + I_T + + + + + + + + + + + + + + + + + + + + + + + + R_v + + + 0.01 + C_T + + + + + I_T + 1-6 + + + + + + + + + t + + q + + + + v + v_T + + + + + u_C + + + + + q + q_us + + C_T + + + + + + u + + + u_C + u_ext + + + R_v + + + v + v_T + + + + + + + + + + t + + v + + + + + + + + u_in + u + + + + + + v + R_T + + 2 + + + I_T + + + + + + + + t + + v_T + + + + + + + + u + u_out + + + + + + v_T + R_T + + 2 + + + I_T + + + + + + + + + + + + + + + + + + + + + + + + R_v + + + 0.01 + C_T + + + + + I_T + 1-6 + + + + + + + + + t + + q + + + + v + v_T + + + + + u_C + + + + + q + q_us + + C_T + + + + + + u + + + u_C + u_ext + + + R_v + + + v + v_T + + + + + + + + + + t + + v + + + + + + + + u_in + u + + + + + + v + R_T + + 2 + + + I_T + + + + + + + + t + + v_T + + + + + + + + u + u_out + + + + + + v_T + R_T + + 2 + + + I_T + + + + + + + + + + + + + + + + + + + + + + + + R_v + + + 0.01 + C_T + + + + + I_T + 1-6 + + + + + + + + + t + + q + + + + v + v_T + + + + + u_C + + + + + q + q_us + + C_T + + + + + + u + + + u_C + u_ext + + + R_v + + + v + v_T + + + + + + + + + + t + + v + + + + + + + + u_in + u + + + + + + v + R_T + + 2 + + + I_T + + + + + + + + t + + v_T + + + + + + + + u + u_out + + + + + + v_T + R_T + + 2 + + + I_T + + + + + + + + + + + + + + + + + + + + + + + + R_v + + + 0.01 + C_T + + + + + I_T + 1-6 + + + + + + + + + t + + q + + + + v + v_T + + + + + u_C + + + + + q + q_us + + C_T + + + + + + u + + + u_C + u_ext + + + R_v + + + v + v_T + + + + + + + + + + t + + v + + + + + + + + u_in + u + + + + + + v + R_T + + 2 + + + I_T + + + + + + + + t + + v_T + + + + + + + + u + u_out + + + + + + v_T + R_T + + 2 + + + I_T + + + + + + + + + + + + + + + + + + + + + + + + R_v + + + 0.01 + C_T + + + + + I_T + 1-6 + + + + + + + + + t + + q + + + + v + v_T + + + + + u_C + + + + + q + q_us + + C_T + + + + + + u + + + u_C + u_ext + + + R_v + + + v + v_T + + + + + + + + + + t + + v + + + + + + + + u_in + u + + + + + + v + R_T + + 2 + + + I_T + + + + + + + + t + + v_T + + + + + + + + u + u_out + + + + + + v_T + R_T + + 2 + + + I_T + + + + + + + + + + + + + + + + + + + + + + + + R_v + + + 0.01 + C_T + + + + + I_T + 1-6 + + + + + + + + + t + + q + + + + v + v_T + + + + + u_C + + + + + q + q_us + + C_T + + + + + + u + + + u_C + u_ext + + + R_v + + + v + v_T + + + + + + + + + + t + + v + + + + + + + + u_in + u + + + + + + v + R_T + + 2 + + + I_T + + + + + + + + t + + v_T + + + + + + + + u + u_out + + + + + + v_T + R_T + + 2 + + + I_T + + + + + + + + + + + + + + + + + + + + + + + + R_v + + + 0.01 + C_T + + + + + I_T + 1-6 + + + + + + + + + t + + q + + + + v + v_T + + + + + u_C + + + + + q + q_us + + C_T + + + + + + u + + + u_C + u_ext + + + R_v + + + v + v_T + + + + + + + + + + t + + v + + + + + + + + u_in + u + + + + + + v + R_T + + 2 + + + I_T + + + + + + + + t + + v_T + + + + + + + + u + u_out + + + + + + v_T + R_T + + 2 + + + I_T + + + + + + + + + + + + + + + + + + + + + + + + R_v + + + 0.01 + C_T + + + + + I_T + 1-6 + + + + + + + + + t + + q + + + + v + v_T + + + + + u_C + + + + + q + q_us + + C_T + + + + + + u + + + u_C + u_ext + + + R_v + + + v + v_T + + + + + + + + + + t + + v + + + + + + + + u_in + u + + + + + + v + R_T + + 2 + + + I_T + + + + + + + + t + + v_T + + + + + + + + u + u_out + + + + + + v_T + R_T + + 2 + + + I_T + + + + + + + + + + + + + + + + + + + + + + + + R_v + + + 0.01 + C_T + + + + + I_T + 1-6 + + + + + + + + + t + + q + + + + v + v_T + + + + + u_C + + + + + q + q_us + + C_T + + + + + + u + + + u_C + u_ext + + + R_v + + + v + v_T + + + + + + + + + + t + + v + + + + + + + + u_in + u + + + + + + v + R_T + + 2 + + + I_T + + + + + + + + t + + v_T + + + + + + + + u + u_out + + + + + + v_T + R_T + + 2 + + + I_T + + + + + + + + + + + + + + + + + + + + + + + + R_v + + + 0.01 + C_T + + + + + I_T + 1-6 + + + + + + + + + t + + q + + + + v + v_T + + + + + u_C + + + + + q + q_us + + C_T + + + + + + u + + + u_C + u_ext + + + R_v + + + v + v_T + + + + + + + + + + t + + v + + + + + + + + u_in + u + + + + + + v + R_T + + 2 + + + I_T + + + + + + + + t + + v_T + + + + + + + + u + u_out + + + + + + v_T + R_T + + 2 + + + I_T + + + + + + + + + + + + + + + + + + + + + + + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + u + u_out + + + + R + v + + + I + + + + + + + + t + + q_C_change + + + + v_in + v + + + + + + q_C + + + + + q_C_change + q_us_0 + + q_us_wCont + + + + + q + + + q_C + q_us_wCont + + + + + u_C + + + + + q_C + C_wCont + + u_ext + + + + + u + + + u_C + + + R_v + + + v_in + v + + + + + + + q_us_wCont + + + q_us_0 + + + 1 + Delta_q_us + + + + + + C_wCont + + + C + + + 1 + Delta_C + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + u + u_out + + + + R + v + + + I + + + + + + + + t + + q_C_change + + + + v_in + v + + + + + + q_C + + + + + q_C_change + q_us_0 + + q_us_wCont + + + + + q + + + q_C + q_us_wCont + + + + + u_C + + + + + q_C + C_wCont + + u_ext + + + + + u + + + u_C + + + R_v + + + v_in + v + + + + + + + q_us_wCont + + + q_us_0 + + + 1 + Delta_q_us + + + + + + C_wCont + + + C + + + 1 + Delta_C + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + u + u_out + + + + R + v + + + I + + + + + + + + t + + q_C_change + + + + v_in + v + + + + + + q_C + + + + + q_C_change + q_us_0 + + q_us_wCont + + + + + q + + + q_C + q_us_wCont + + + + + u_C + + + + + q_C + C_wCont + + u_ext + + + + + u + + + u_C + + + R_v + + + v_in + v + + + + + + + q_us_wCont + + + q_us_0 + + + 1 + Delta_q_us + + + + + + C_wCont + + + C + + + 1 + Delta_C + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + u + u_out + + + + R + v + + + I + + + + + + + + t + + q_C_change + + + + v_in + v + + + + + + q_C + + + + + q_C_change + q_us_0 + + q_us_wCont + + + + + q + + + q_C + q_us_wCont + + + + + u_C + + + + + q_C + C_wCont + + u_ext + + + + + u + + + u_C + + + R_v + + + v_in + v + + + + + + + q_us_wCont + + + q_us_0 + + + 1 + Delta_q_us + + + + + + C_wCont + + + C + + + 1 + Delta_C + + + + + + + + + + + + + + + + + + + + + + + + + t + + P_baro + + + + + + + + P_sys + + + tau_zb + dP_sys_dt + + + P_baro + + tau_pb + + + + + f_ab + + + + + f_ab_min + + + f_ab_max + + + + + + + P_baro + P_nom + + k_ab + + + + + + + 1 + + + + + + + P_baro + P_nom + + k_ab + + + + + + + + + + + + + + + + + + + + + + f_v + + + + + + + + + f_ev_0 + + + f_ev_inf + + + + + + + f_ab + f_ab_0 + + k_ev + + + + + + + 1 + + + + + + + f_ab + f_ab_0 + + k_ev + + + + + + + W_cv + f_apc + + + theta_v + + + + + + + + + + + + + + + + + + + + f_s_premax + + + f_es_inf + + + + + f_es_0 + f_es_inf + + + + + + k_es + + + + + W_bs + f_ab + + + + W_cs + f_apc + + + + + + + + + + + f_s + + + f_s_premax + + + f_s_premax + f_es_max + + + + f_es_max + + + + + + + + + + + + + + + + + sigma_theta + + + + + G_theta + + + + + 1 + + + + + f_s + f_es_min + + 1 + + + + + + + f_s + f_es_min + + + + 0 + + + + + + + + + t + + Delta_theta + + + + + + + + Delta_theta + + sigma_theta + + tau_theta + + + + + + + + + + + + + + + + sigma_theta + + + + + G_theta + + + + + 1 + + + + + f_s + f_es_min + + 1 + + + + + + + f_s + f_es_min + + + + 0 + + + + + + + + + t + + Delta_theta + + + + + + + + Delta_theta + + sigma_theta + + tau_theta + + + + + + + + + + + + + + + + sigma_theta + + + + + G_theta + + + + + 1 + + + + + f_s + f_es_min + + 1 + + + + + + + f_s + f_es_min + + + + 0 + + + + + + + + + t + + Delta_theta + + + + + + + + Delta_theta + + sigma_theta + + tau_theta + + + + + + + + + + + + + + + + sigma_theta + + + + + G_theta + + + + + 1 + + + + + f_s + f_es_min + + 1 + + + + + + + f_s + f_es_min + + + + 0 + + + + + + + + + t + + Delta_theta + + + + + + + + Delta_theta + + sigma_theta + + tau_theta + + + + + + + + + + + + + + + + + + + + + + sigma_Ts + + + + + G_Ts + + + + + 1 + + + + + f_s + f_es_min + + 1 + + + + + + + f_s + f_es_min + + + + 0 + + + + + + + + + t + + Delta_Ts + + + + + + + + Delta_Ts + + sigma_Ts + + tau_Ts + + + + + sigma_Tv + + + G_Tv + f_v + + + + + + + + + t + + Delta_Tv + + + + + + + + Delta_Tv + + sigma_Tv + + tau_Tv + + + + + Delta_T + + + Delta_Tv + Delta_Ts + + + + + + + + + + + + + + + + + + + + + + + t + + sigma_theta_us + + + + + + + + + + f_s + f_es_min + + 0 + + sigma_theta_us + + tau_theta_us + + + + + Delta_theta_us + + + + + G_theta_compliance + sigma_theta_us + + + + f_es_min + sigma_theta_us + + + + + + + + + t + + sigma_theta_compliance + + + + + + + + + + f_s + f_es_min + + 0 + + sigma_theta_compliance + + tau_theta_compliance + + + + + Delta_theta_compliance + + + + + G_theta_compliance + sigma_theta_compliance + + + + f_es_min + sigma_theta_compliance + + + + + + + + + + + + + + + + + + + + + + + + + q + + + q_C + q_0 + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + u + u_out + + + + R + v + + + I + + + + + + + + t + + q_C + + + + v_in + v + + + + + u_C + + + + + q_C + C + + u_ext + + + + + u + + + u_0 + u_C + + + R_v + + + v_in + v + + + + + + + + + + + + + + + + + + + + + + + + + + q + + + q_C + q_0 + + + + + R_v + + + 0.01 + C + + + + + + + + + t + + v + + + + + + + + u + u_out + + + + R + v + + + I + + + + + + + + t + + q_C + + + + v_in + v + + + + + u_C + + + + + q_C + C + + u_ext + + + + + u + + + u_0 + u_C + + + R_v + + + v_in + v + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + v_venous_lb + + + v_A_internal_iliac_L_T + v_A_internal_iliac_R_T + v_A_profunda_femoris_L_T + v_A_profunda_femoris_R_T + v_A_anterior_tibial_L_T + v_A_anterior_tibial_R_T + v_A_posterior_tibial_L_T + v_A_fibular_L_T + v_A_fibular_R_T + v_A_posterior_tibial_R_T + + + + + + + v_venous_ub + + + v_A_left_gastric_C_T + v_A_common_hepatic_C_T + v_A_splenic_C_T + v_A_superior_mesenteric_C_T + v_A_renal_L_T + v_A_renal_R_T + v_A_inferior_mesenteric_C_T + v_A_radial_L_T + v_A_ulnar_L_T + v_A_radial_R_T + v_A_ulnar_R_T + v_A_external_carotid_L_T + v_A_external_carotid_R_T + v_A_posterior_inferior_cerebellar_R_T + v_A_posterior_inferior_cerebellar_L_T + v_A_anterior_inferior_cerebellar_R_T + v_A_anterior_inferior_cerebellar_L_T + v_A_superior_cerebellar_L_T + v_A_middle_cerebral_L_T + v_A_superior_cerebellar_R_T + v_A_middle_cerebral_R_T + v_A_posterior_cerebral_postcommunicating_part_L_T + v_A_posterior_cerebral_postcommunicating_part_R_T + v_A_anterior_cerebral_L_2_T + v_A_anterior_cerebral_R_2_T + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 00c308d03c947179d412600e4376a2b4e50a79fb Mon Sep 17 00:00:00 2001 From: Alan Garny Date: Thu, 9 Apr 2026 10:51:31 +1200 Subject: [PATCH 02/12] Generator: use the analyser model's areEquivalentVariables() method. ... rather than the generic areEquivalentVariables() method which doesn't include caching. --- src/generator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/generator.cpp b/src/generator.cpp index 20cc41e81..be3bd6096 100644 --- a/src/generator.cpp +++ b/src/generator.cpp @@ -1945,7 +1945,7 @@ std::string Generator::GeneratorImpl::generateInitialiseVariableCode(const Analy || (generatedConstantDependencies != nullptr)) { auto initialisingAnalyserVariable = std::find_if(remainingVariables.begin(), remainingVariables.end(), [&](const AnalyserVariablePtr &av) { - return areEquivalentVariables(initialValueVariable, av->variable()); + return mAnalyserModel->areEquivalentVariables(initialValueVariable, av->variable()); }); if (initialisingAnalyserVariable != remainingVariables.end()) { From ae845f51e6c203ff7797ca74889cdbb69386f0c3 Mon Sep 17 00:00:00 2001 From: Alan Garny Date: Thu, 9 Apr 2026 01:55:10 +1200 Subject: [PATCH 03/12] AnalyserModel: improved and fixed areEquivalentVariables(). Indeed, in our WebAssembly module, the key was 32-bit (while 64-bit in C++/Python) which caused collisions and incorrect cache hits. So, we replaced the Cantor-pairing key and std::map-based cache with a typed VariableKeyPair and std::unordered_map. This makes the cached-equivalence lookup more explicit, portable, and efficient. --- src/CMakeLists.txt | 4 ++++ src/analysermodel.cpp | 19 +++++++------------ src/analysermodel_p.h | 41 ++++++++++++++++++++++++++++++++++++++--- 3 files changed, 49 insertions(+), 15 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 466fb2930..f9956e386 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -303,6 +303,10 @@ if(LIBCELLML_LLVM_COVERAGE) append_target_property(cellml LINK_FLAGS "-fprofile-instr-generate") endif() +if(LIBCELLML_COVERAGE OR LIBCELLML_LLVM_COVERAGE) + target_compile_definitions(cellml PRIVATE CODE_COVERAGE_ENABLED) +endif() + install(TARGETS cellml EXPORT libcellml-targets COMPONENT runtime RUNTIME DESTINATION bin diff --git a/src/analysermodel.cpp b/src/analysermodel.cpp index 74dbb1f71..fe6c16ca7 100644 --- a/src/analysermodel.cpp +++ b/src/analysermodel.cpp @@ -496,25 +496,20 @@ bool AnalyserModel::areEquivalentVariables(const VariablePtr &variable1, // an AnalyserModel object refers to a static version of a model, which // means that we can safely cache the result of a call to that utility. In // turn, this means that we can speed up any feature (e.g., code generation) - // that also relies on that utility. When it comes to the key for the cache, - // we use the Cantor pairing function with the address of the two variables - // as parameters, thus ensuring the uniqueness of the key (see - // https://en.wikipedia.org/wiki/Pairing_function#Cantor_pairing_function). + // that also relies on that utility. auto v1 = reinterpret_cast(variable1.get()); auto v2 = reinterpret_cast(variable2.get()); - if (v2 < v1) { - v1 += v2; - v2 = v1 - v2; - v1 = v1 - v2; + if (v1 > v2) { + std::swap(v1, v2); } - auto key = ((v1 + v2) * (v1 + v2 + 1) >> 1U) + v2; - auto cacheKey = mPimpl->mCachedEquivalentVariables.find(key); + auto key = AnalyserModel::AnalyserModelImpl::VariableKeyPair {v1, v2}; + auto it = mPimpl->mCachedEquivalentVariables.find(key); - if (cacheKey != mPimpl->mCachedEquivalentVariables.end()) { - return cacheKey->second; + if (it != mPimpl->mCachedEquivalentVariables.end()) { + return it->second; } auto res = libcellml::areEquivalentVariables(variable1, variable2); diff --git a/src/analysermodel_p.h b/src/analysermodel_p.h index 41d3f5e9f..5c557b88a 100644 --- a/src/analysermodel_p.h +++ b/src/analysermodel_p.h @@ -16,7 +16,8 @@ limitations under the License. #pragma once -#include +#include +#include #include "libcellml/analysermodel.h" @@ -45,6 +46,42 @@ struct AnalyserModel::AnalyserModelImpl std::vector mAnalyserEquations; + struct VariableKeyPair + { + uintptr_t first; + uintptr_t second; + + bool operator==(const VariableKeyPair &other) const + { +#ifdef CODE_COVERAGE_ENABLED + // Use a branchless form so coverage does not depend on short-circuit behaviour. + + const auto firstEqual = static_cast(first == other.first); + const auto secondEqual = static_cast(second == other.second); + + return firstEqual * secondEqual != 0; +#else + return first == other.first && second == other.second; +#endif + } + }; + + struct VariableKeyPairHash + { + size_t operator()(const VariableKeyPair &pair) const + { + // A simple and portable hash function for a pair of pointers. + + size_t hash = pair.first; + + hash ^= pair.second + 0x9e3779b9 + (hash << 6) + (hash >> 2); + + return hash; + } + }; + + std::unordered_map mCachedEquivalentVariables; + bool mNeedEqFunction = false; bool mNeedNeqFunction = false; bool mNeedLtFunction = false; @@ -72,8 +109,6 @@ struct AnalyserModel::AnalyserModelImpl bool mNeedAcschFunction = false; bool mNeedAcothFunction = false; - std::map mCachedEquivalentVariables; - static AnalyserModelPtr create(const ModelPtr &model = nullptr); AnalyserModelImpl(const ModelPtr &model); From 2330fa35430173dced6887a976418e12f251ccf2 Mon Sep 17 00:00:00 2001 From: Alan Garny Date: Tue, 14 Apr 2026 19:14:01 +1200 Subject: [PATCH 04/12] macOS: support macOS 14 and later. Only support the three most recent versions of macOS, not to mention that we want to be able to use `std::format()` which is only available on macOS 13 and later. --- .github/workflows/deploy-on-release.yml | 4 ++-- CMakeLists.txt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/deploy-on-release.yml b/.github/workflows/deploy-on-release.yml index b074781f6..a7d6f7121 100644 --- a/.github/workflows/deploy-on-release.yml +++ b/.github/workflows/deploy-on-release.yml @@ -322,11 +322,11 @@ jobs: if [[ "${{ matrix.py }}" == "3.8" ]]; then echo "Setting macos_archs as: macos_archs='x86_64'" echo "macos_archs=x86_64" >> $GITHUB_OUTPUT - echo "macos_deployment_target=10.15" >> $GITHUB_OUTPUT + echo "macos_deployment_target=14" >> $GITHUB_OUTPUT else echo "Setting macos_archs as: macos_archs='x86_64 arm64'" echo 'macos_archs=x86_64 arm64' >> $GITHUB_OUTPUT - echo "macos_deployment_target=11.0" >> $GITHUB_OUTPUT + echo "macos_deployment_target=14" >> $GITHUB_OUTPUT fi else echo "Setting macos_archs as: macos_archs='x86_64'" diff --git a/CMakeLists.txt b/CMakeLists.txt index e52f3c32e..21115f6bb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,7 +14,7 @@ cmake_minimum_required(VERSION 3.18.0) -set(CMAKE_OSX_DEPLOYMENT_TARGET 10.15 CACHE STRING "Minimum OS X deployment version.") +set(CMAKE_OSX_DEPLOYMENT_TARGET 14 CACHE STRING "Minimum OS X deployment version.") set(PROJECT_NAME libCellML) set(PROJECT_URL https://libcellml.org) From 6c970b755dc782c202fac34e31d2ee2346a41847 Mon Sep 17 00:00:00 2001 From: Alan Garny Date: Tue, 14 Apr 2026 12:14:26 +1200 Subject: [PATCH 05/12] Improvements to the overall speed and memory use of libCellML. --- CMakeLists.txt | 5 + src/analyser.cpp | 275 +++++--- src/analyser_p.h | 16 +- src/analyserequation.cpp | 12 +- src/analyserequationast.cpp | 2 +- src/analyserexternalvariable.cpp | 6 +- src/analysermodel.cpp | 39 +- src/analysermodel_p.h | 2 + src/analyservariable.cpp | 2 + src/annotator.cpp | 45 +- src/api/libcellml/analyserequation.h | 8 +- src/api/libcellml/analyserequationast.h | 2 +- src/api/libcellml/analyserexternalvariable.h | 2 +- src/api/libcellml/analysermodel.h | 12 +- src/api/libcellml/component.h | 2 +- src/api/libcellml/componententity.h | 2 +- src/api/libcellml/entity.h | 2 +- src/api/libcellml/generatorprofile.h | 338 +++++----- src/api/libcellml/importedentity.h | 2 +- src/api/libcellml/importsource.h | 2 +- src/api/libcellml/issue.h | 2 +- src/api/libcellml/namedentity.h | 2 +- src/api/libcellml/reset.h | 8 +- src/api/libcellml/variable.h | 4 +- src/commonutils.cpp | 14 +- src/component.cpp | 8 +- src/componententity.cpp | 6 +- src/debug.cpp | 1 + src/entity.cpp | 2 +- src/generator.cpp | 651 ++++++++++++------- src/generator_p.h | 24 +- src/generatorprofile.cpp | 338 +++++----- src/generatorprofiletools.cpp | 2 + src/generatorvariabletracker.cpp | 10 +- src/importedentity.cpp | 2 +- src/importer.cpp | 36 +- src/importsource.cpp | 2 +- src/internaltypes.h | 9 +- src/issue.cpp | 2 +- src/model.cpp | 10 +- src/namedentity.cpp | 2 +- src/parser.cpp | 13 +- src/printer.cpp | 139 ++-- src/reset.cpp | 8 +- src/units.cpp | 25 +- src/utilities.cpp | 83 +-- src/utilities.h | 2 +- src/validator.cpp | 182 +++--- src/variable.cpp | 10 +- src/xmlattribute.cpp | 23 +- src/xmldoc.cpp | 8 +- src/xmlnode.cpp | 39 +- src/xmlnode.h | 13 +- tests/coverage/coverage.cpp | 39 ++ tests/generator/generator.cpp | 8 +- 55 files changed, 1443 insertions(+), 1060 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 21115f6bb..4258eb7a9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,6 +22,11 @@ set(_PROJECT_VERSION 0.6.3) set(PROJECT_DEVELOPER_VERSION) project(${PROJECT_NAME} VERSION ${_PROJECT_VERSION} LANGUAGES CXX) +# Set the C++ standard to be used for all targets. +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + # Set policies that affect the build. set(NEW_POLICIES CMP0056 CMP0063 CMP0074 CMP0078 CMP0086 CMP0092) foreach(NEW_POLICY ${NEW_POLICIES}) diff --git a/src/analyser.cpp b/src/analyser.cpp index e79550d27..dfa136f3c 100644 --- a/src/analyser.cpp +++ b/src/analyser.cpp @@ -21,7 +21,9 @@ limitations under the License. #include "libcellml/analyser.h" #include +#include #include +#include #include "libcellml/analyserequation.h" #include "libcellml/analyserexternalvariable.h" @@ -40,7 +42,7 @@ namespace libcellml { AnalyserInternalVariablePtr AnalyserInternalVariable::create(const VariablePtr &variable) { - auto res = AnalyserInternalVariablePtr {new AnalyserInternalVariable {}}; + auto res = std::make_shared(); res->setVariable(variable); @@ -91,7 +93,7 @@ void AnalyserInternalVariable::makeConstant() AnalyserInternalEquationPtr AnalyserInternalEquation::create(const ComponentPtr &component) { - auto res = AnalyserInternalEquationPtr {new AnalyserInternalEquation {}}; + auto res = std::make_shared(); res->mAst = AnalyserEquationAst::create(); res->mComponent = component; @@ -101,18 +103,19 @@ AnalyserInternalEquationPtr AnalyserInternalEquation::create(const ComponentPtr AnalyserInternalEquationPtr AnalyserInternalEquation::create(const AnalyserInternalVariablePtr &variable) { - auto res = AnalyserInternalEquationPtr {new AnalyserInternalEquation {}}; + auto res = std::make_shared(); res->mComponent = owningComponent(variable->mVariable); res->mUnknownVariables.push_back(variable); + res->mUnknownVariablesSet.insert(variable.get()); return res; } void AnalyserInternalEquation::addVariable(const AnalyserInternalVariablePtr &variable) { - if (std::find(mVariables.begin(), mVariables.end(), variable) == mVariables.end()) { + if (mVariablesSet.insert(variable.get()).second) { mVariables.push_back(variable); mAllVariables.push_back(variable); } @@ -120,7 +123,7 @@ void AnalyserInternalEquation::addVariable(const AnalyserInternalVariablePtr &va void AnalyserInternalEquation::addStateVariable(const AnalyserInternalVariablePtr &stateVariable) { - if (std::find(mStateVariables.begin(), mStateVariables.end(), stateVariable) == mStateVariables.end()) { + if (mStateVariablesSet.insert(stateVariable.get()).second) { mStateVariables.push_back(stateVariable); mAllVariables.push_back(stateVariable); } @@ -226,6 +229,20 @@ bool AnalyserInternalEquation::check(const AnalyserModelPtr &analyserModel, bool mVariables.erase(std::remove_if(mVariables.begin(), mVariables.end(), isKnownVariable), mVariables.end()); mStateVariables.erase(std::remove_if(mStateVariables.begin(), mStateVariables.end(), isKnownStateVariable), mStateVariables.end()); + // Rebuild our companion sets. + + mVariablesSet.clear(); + + for (const auto &variable : mVariables) { + mVariablesSet.insert(variable.get()); + } + + mStateVariablesSet.clear(); + + for (const auto &stateVariable : mStateVariables) { + mStateVariablesSet.insert(stateVariable.get()); + } + // If there is no (state) variable left then it means that the variables in // the equation are overconstrained unless one of them was initialised in // which case it will now be considered as an algebraic variable and this @@ -314,6 +331,7 @@ bool AnalyserInternalEquation::check(const AnalyserModelPtr &analyserModel, bool variable->mIsKnownStateVariable = variable->mType == AnalyserInternalVariable::Type::STATE; mUnknownVariables.push_back(variable); + mUnknownVariablesSet.insert(variable.get()); break; default: @@ -399,11 +417,22 @@ Analyser::AnalyserImpl::AnalyserImpl() AnalyserInternalVariablePtr Analyser::AnalyserImpl::internalVariable(const VariablePtr &variable) { - // Find and return, if there is one, the internal variable associated with - // the given variable. + // Check the direct pointer cache first. + + auto cacheIt = mInternalVariableCache.find(variable.get()); + + if (cacheIt != mInternalVariableCache.end()) { + return cacheIt->second; + } + + // Not in the cache, so do the equivalence-based search. for (const auto &internalVariable : mInternalVariables) { if (mAnalyserModel->areEquivalentVariables(variable, internalVariable->mVariable)) { + // Cache this internal variable pointer for future lookups. + + mInternalVariableCache.emplace(variable.get(), internalVariable); + return internalVariable; } } @@ -414,6 +443,7 @@ AnalyserInternalVariablePtr Analyser::AnalyserImpl::internalVariable(const Varia auto res = AnalyserInternalVariable::create(variable); mInternalVariables.push_back(res); + mInternalVariableCache.emplace(variable.get(), res); return res; } @@ -454,8 +484,11 @@ void Analyser::AnalyserImpl::analyseNode(const XmlNodePtr &node, } // Basic content elements. + // Note: we don't need to check for the MathML namespace here since we can only analyse if a model is valid. + + const char *elemName = node->rawName(); - if (node->isMathmlElement("apply")) { + if (strcmp(elemName, "apply") == 0) { // We may have 1, 2, 3 or more child nodes, e.g. // // +--------+ @@ -514,7 +547,7 @@ void Analyser::AnalyserImpl::analyseNode(const XmlNodePtr &node, // Relational and logical operators. - } else if (node->isMathmlElement("eq")) { + } else if (strcmp(elemName, "eq") == 0) { // This element is used both to describe "a = b" and "a == b". We can // distinguish between the two by checking its grandparent. If it's a // "math" element then it means that it is used to describe "a = b" @@ -527,163 +560,163 @@ void Analyser::AnalyserImpl::analyseNode(const XmlNodePtr &node, mAnalyserModel->mPimpl->mNeedEqFunction = true; } - } else if (node->isMathmlElement("neq")) { + } else if (strcmp(elemName, "neq") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::NEQ, astParent); mAnalyserModel->mPimpl->mNeedNeqFunction = true; - } else if (node->isMathmlElement("lt")) { + } else if (strcmp(elemName, "lt") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::LT, astParent); mAnalyserModel->mPimpl->mNeedLtFunction = true; - } else if (node->isMathmlElement("leq")) { + } else if (strcmp(elemName, "leq") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::LEQ, astParent); mAnalyserModel->mPimpl->mNeedLeqFunction = true; - } else if (node->isMathmlElement("gt")) { + } else if (strcmp(elemName, "gt") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::GT, astParent); mAnalyserModel->mPimpl->mNeedGtFunction = true; - } else if (node->isMathmlElement("geq")) { + } else if (strcmp(elemName, "geq") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::GEQ, astParent); mAnalyserModel->mPimpl->mNeedGeqFunction = true; - } else if (node->isMathmlElement("and")) { + } else if (strcmp(elemName, "and") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::AND, astParent); mAnalyserModel->mPimpl->mNeedAndFunction = true; - } else if (node->isMathmlElement("or")) { + } else if (strcmp(elemName, "or") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::OR, astParent); mAnalyserModel->mPimpl->mNeedOrFunction = true; - } else if (node->isMathmlElement("xor")) { + } else if (strcmp(elemName, "xor") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::XOR, astParent); mAnalyserModel->mPimpl->mNeedXorFunction = true; - } else if (node->isMathmlElement("not")) { + } else if (strcmp(elemName, "not") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::NOT, astParent); mAnalyserModel->mPimpl->mNeedNotFunction = true; // Arithmetic operators. - } else if (node->isMathmlElement("plus")) { + } else if (strcmp(elemName, "plus") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::PLUS, astParent); - } else if (node->isMathmlElement("minus")) { + } else if (strcmp(elemName, "minus") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::MINUS, astParent); - } else if (node->isMathmlElement("times")) { + } else if (strcmp(elemName, "times") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::TIMES, astParent); - } else if (node->isMathmlElement("divide")) { + } else if (strcmp(elemName, "divide") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::DIVIDE, astParent); - } else if (node->isMathmlElement("power")) { + } else if (strcmp(elemName, "power") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::POWER, astParent); - } else if (node->isMathmlElement("root")) { + } else if (strcmp(elemName, "root") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::ROOT, astParent); - } else if (node->isMathmlElement("abs")) { + } else if (strcmp(elemName, "abs") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::ABS, astParent); - } else if (node->isMathmlElement("exp")) { + } else if (strcmp(elemName, "exp") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::EXP, astParent); - } else if (node->isMathmlElement("ln")) { + } else if (strcmp(elemName, "ln") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::LN, astParent); - } else if (node->isMathmlElement("log")) { + } else if (strcmp(elemName, "log") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::LOG, astParent); - } else if (node->isMathmlElement("ceiling")) { + } else if (strcmp(elemName, "ceiling") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::CEILING, astParent); - } else if (node->isMathmlElement("floor")) { + } else if (strcmp(elemName, "floor") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::FLOOR, astParent); - } else if (node->isMathmlElement("min")) { + } else if (strcmp(elemName, "min") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::MIN, astParent); mAnalyserModel->mPimpl->mNeedMinFunction = true; - } else if (node->isMathmlElement("max")) { + } else if (strcmp(elemName, "max") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::MAX, astParent); mAnalyserModel->mPimpl->mNeedMaxFunction = true; - } else if (node->isMathmlElement("rem")) { + } else if (strcmp(elemName, "rem") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::REM, astParent); // Calculus elements. - } else if (node->isMathmlElement("diff")) { + } else if (strcmp(elemName, "diff") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::DIFF, astParent); // Trigonometric operators. - } else if (node->isMathmlElement("sin")) { + } else if (strcmp(elemName, "sin") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::SIN, astParent); - } else if (node->isMathmlElement("cos")) { + } else if (strcmp(elemName, "cos") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::COS, astParent); - } else if (node->isMathmlElement("tan")) { + } else if (strcmp(elemName, "tan") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::TAN, astParent); - } else if (node->isMathmlElement("sec")) { + } else if (strcmp(elemName, "sec") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::SEC, astParent); mAnalyserModel->mPimpl->mNeedSecFunction = true; - } else if (node->isMathmlElement("csc")) { + } else if (strcmp(elemName, "csc") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::CSC, astParent); mAnalyserModel->mPimpl->mNeedCscFunction = true; - } else if (node->isMathmlElement("cot")) { + } else if (strcmp(elemName, "cot") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::COT, astParent); mAnalyserModel->mPimpl->mNeedCotFunction = true; - } else if (node->isMathmlElement("sinh")) { + } else if (strcmp(elemName, "sinh") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::SINH, astParent); - } else if (node->isMathmlElement("cosh")) { + } else if (strcmp(elemName, "cosh") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::COSH, astParent); - } else if (node->isMathmlElement("tanh")) { + } else if (strcmp(elemName, "tanh") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::TANH, astParent); - } else if (node->isMathmlElement("sech")) { + } else if (strcmp(elemName, "sech") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::SECH, astParent); mAnalyserModel->mPimpl->mNeedSechFunction = true; - } else if (node->isMathmlElement("csch")) { + } else if (strcmp(elemName, "csch") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::CSCH, astParent); mAnalyserModel->mPimpl->mNeedCschFunction = true; - } else if (node->isMathmlElement("coth")) { + } else if (strcmp(elemName, "coth") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::COTH, astParent); mAnalyserModel->mPimpl->mNeedCothFunction = true; - } else if (node->isMathmlElement("arcsin")) { + } else if (strcmp(elemName, "arcsin") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::ASIN, astParent); - } else if (node->isMathmlElement("arccos")) { + } else if (strcmp(elemName, "arccos") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::ACOS, astParent); - } else if (node->isMathmlElement("arctan")) { + } else if (strcmp(elemName, "arctan") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::ATAN, astParent); - } else if (node->isMathmlElement("arcsec")) { + } else if (strcmp(elemName, "arcsec") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::ASEC, astParent); mAnalyserModel->mPimpl->mNeedAsecFunction = true; - } else if (node->isMathmlElement("arccsc")) { + } else if (strcmp(elemName, "arccsc") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::ACSC, astParent); mAnalyserModel->mPimpl->mNeedAcscFunction = true; - } else if (node->isMathmlElement("arccot")) { + } else if (strcmp(elemName, "arccot") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::ACOT, astParent); mAnalyserModel->mPimpl->mNeedAcotFunction = true; - } else if (node->isMathmlElement("arcsinh")) { + } else if (strcmp(elemName, "arcsinh") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::ASINH, astParent); - } else if (node->isMathmlElement("arccosh")) { + } else if (strcmp(elemName, "arccosh") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::ACOSH, astParent); - } else if (node->isMathmlElement("arctanh")) { + } else if (strcmp(elemName, "arctanh") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::ATANH, astParent); - } else if (node->isMathmlElement("arcsech")) { + } else if (strcmp(elemName, "arcsech") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::ASECH, astParent); mAnalyserModel->mPimpl->mNeedAsechFunction = true; - } else if (node->isMathmlElement("arccsch")) { + } else if (strcmp(elemName, "arccsch") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::ACSCH, astParent); mAnalyserModel->mPimpl->mNeedAcschFunction = true; - } else if (node->isMathmlElement("arccoth")) { + } else if (strcmp(elemName, "arccoth") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::ACOTH, astParent); mAnalyserModel->mPimpl->mNeedAcothFunction = true; // Piecewise statement. - } else if (node->isMathmlElement("piecewise")) { + } else if (strcmp(elemName, "piecewise") == 0) { auto childCount = mathmlChildCount(node); ast->mPimpl->populate(AnalyserEquationAst::Type::PIECEWISE, astParent); @@ -713,19 +746,19 @@ void Analyser::AnalyserImpl::analyseNode(const XmlNodePtr &node, ast->mPimpl->mOwnedRightChild = astRight; } - } else if (node->isMathmlElement("piece")) { + } else if (strcmp(elemName, "piece") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::PIECE, astParent); analyseNode(mathmlChildNode(node, 0), ast->mPimpl->mOwnedLeftChild, ast, component, equation); analyseNode(mathmlChildNode(node, 1), ast->mPimpl->mOwnedRightChild, ast, component, equation); - } else if (node->isMathmlElement("otherwise")) { + } else if (strcmp(elemName, "otherwise") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::OTHERWISE, astParent); analyseNode(mathmlChildNode(node, 0), ast->mPimpl->mOwnedLeftChild, ast, component, equation); // Token elements. - } else if (node->isMathmlElement("ci")) { + } else if (strcmp(elemName, "ci") == 0) { auto variableName = node->firstChild()->convertToStrippedString(); auto variable = component->variable(variableName); // Note: we always have a variable. Indeed, if we were not to have one, @@ -748,7 +781,7 @@ void Analyser::AnalyserImpl::analyseNode(const XmlNodePtr &node, ast->mPimpl->populate(AnalyserEquationAst::Type::CI, variable, astParent); mCiCnUnits.emplace(ast, variable->units()); - } else if (node->isMathmlElement("cn")) { + } else if (strcmp(elemName, "cn") == 0) { // Add the number to our AST and keep track of its unit. Note that in // the case of a standard unit, we need to create a units since it's // not declared in the model. @@ -780,15 +813,15 @@ void Analyser::AnalyserImpl::analyseNode(const XmlNodePtr &node, // Qualifier elements. - } else if (node->isMathmlElement("degree")) { + } else if (strcmp(elemName, "degree") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::DEGREE, astParent); analyseNode(mathmlChildNode(node, 0), ast->mPimpl->mOwnedLeftChild, ast, component, equation); - } else if (node->isMathmlElement("logbase")) { + } else if (strcmp(elemName, "logbase") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::LOGBASE, astParent); analyseNode(mathmlChildNode(node, 0), ast->mPimpl->mOwnedLeftChild, ast, component, equation); - } else if (node->isMathmlElement("bvar")) { + } else if (strcmp(elemName, "bvar") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::BVAR, astParent); analyseNode(mathmlChildNode(node, 0), ast->mPimpl->mOwnedLeftChild, ast, component, equation); @@ -801,15 +834,15 @@ void Analyser::AnalyserImpl::analyseNode(const XmlNodePtr &node, // Constants. - } else if (node->isMathmlElement("true")) { + } else if (strcmp(elemName, "true") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::TRUE, astParent); - } else if (node->isMathmlElement("false")) { + } else if (strcmp(elemName, "false") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::FALSE, astParent); - } else if (node->isMathmlElement("exponentiale")) { + } else if (strcmp(elemName, "exponentiale") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::E, astParent); - } else if (node->isMathmlElement("pi")) { + } else if (strcmp(elemName, "pi") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::PI, astParent); - } else if (node->isMathmlElement("infinity")) { + } else if (strcmp(elemName, "infinity") == 0) { ast->mPimpl->populate(AnalyserEquationAst::Type::INF, astParent); } else { // We have checked for everything, so if we reach this point it means @@ -950,16 +983,16 @@ void Analyser::AnalyserImpl::analyseComponentVariables(const ComponentPtr &compo } } -void Analyser::AnalyserImpl::equivalentVariables(const VariablePtr &variable, - VariablePtrs &equivVariables) const +void Analyser::AnalyserImpl::equivalentVariables(const VariablePtr &variable, VariablePtrs &equivVariables, + std::unordered_set &seen) const { for (size_t i = 0; i < variable->equivalentVariableCount(); ++i) { auto equivVariable = variable->equivalentVariable(i); - if (std::find(equivVariables.begin(), equivVariables.end(), equivVariable) == equivVariables.end()) { + if (seen.insert(equivVariable.get()).second) { equivVariables.push_back(equivVariable); - equivalentVariables(equivVariable, equivVariables); + equivalentVariables(equivVariable, equivVariables, seen); } } } @@ -967,8 +1000,9 @@ void Analyser::AnalyserImpl::equivalentVariables(const VariablePtr &variable, VariablePtrs Analyser::AnalyserImpl::equivalentVariables(const VariablePtr &variable) const { VariablePtrs res = {variable}; + std::unordered_set seen = {variable.get()}; - equivalentVariables(variable, res); + equivalentVariables(variable, res, seen); return res; } @@ -1203,6 +1237,8 @@ UnitsMaps Analyser::AnalyserImpl::multiplyDivideUnitsMaps(const UnitsMaps &first UnitsMaps res; + res.reserve(firstUnitsMaps.size() * secondUnitsMaps.size()); + for (const auto &firstUnitsMap : firstUnitsMaps) { for (const auto &secondUnitsMap : secondUnitsMaps) { res.push_back(multiplyDivideUnitsMaps(firstUnitsMap, secondUnitsMap, multiply)); @@ -1250,6 +1286,8 @@ UnitsMultipliers Analyser::AnalyserImpl::multiplyDivideUnitsMultipliers(const Un UnitsMultipliers res; + res.reserve(firstUnitsMultipliers.size() * secondUnitsMultipliers.size()); + for (const auto &firstUnitsMultiplier : firstUnitsMultipliers) { for (const auto &secondUnitsMultiplier : secondUnitsMultipliers) { res.push_back(multiplyDivideUnitsMultipliers(firstUnitsMultiplier, @@ -1270,6 +1308,8 @@ UnitsMultipliers Analyser::AnalyserImpl::multiplyDivideUnitsMultipliers(double f UnitsMultipliers res; + res.reserve(secondUnitsMultipliers.size()); + for (const auto &secondUnitsMultiplier : secondUnitsMultipliers) { res.push_back(multiplyDivideUnitsMultipliers(firstUnitsMultiplier, secondUnitsMultiplier, @@ -1289,6 +1329,8 @@ UnitsMultipliers Analyser::AnalyserImpl::powerRootUnitsMultipliers(const UnitsMu UnitsMultipliers res; auto realFactor = power ? factor : 1.0 / factor; + res.reserve(unitsMultipliers.size()); + for (const auto &unitsMultiplier : unitsMultipliers) { res.push_back(realFactor * unitsMultiplier); } @@ -1980,6 +2022,8 @@ void Analyser::AnalyserImpl::analyseEquationUnits(const AnalyserEquationAstPtr & if (!isDimensionlessUnitsMaps) { auto isDimensionlessRightUnitsMaps = Analyser::AnalyserImpl::isDimensionlessUnitsMaps(rightUnitsMaps); + issueDescription.reserve(512); + issueDescription = "The unit"; if (!isDimensionlessRightUnitsMaps) { @@ -2250,14 +2294,12 @@ bool Analyser::AnalyserImpl::isExternalVariable(const AnalyserInternalVariablePt } bool Analyser::AnalyserImpl::isStateRateBased(const AnalyserEquationPtr &analyserEquation, - AnalyserEquationPtrs &checkedEquations) + std::unordered_set &checkedEquations) { - if (std::find(checkedEquations.begin(), checkedEquations.end(), analyserEquation) != checkedEquations.end()) { + if (!checkedEquations.insert(analyserEquation.get()).second) { return false; } - checkedEquations.push_back(analyserEquation); - for (const auto &dependency : analyserEquation->dependencies()) { // A rate is computed either through an ODE equation or through an NLA // equation in case the rate is not on its own on either the LHS or RHS @@ -2320,6 +2362,7 @@ void Analyser::AnalyserImpl::analyseModel(const ModelPtr &model) mAnalyserModel = AnalyserModel::AnalyserModelImpl::create(model); mInternalVariables.clear(); + mInternalVariableCache.clear(); mInternalEquations.clear(); mCiCnUnits.clear(); @@ -2353,7 +2396,7 @@ void Analyser::AnalyserImpl::analyseModel(const ModelPtr &model) // Mark some variables as external variables, should there be some and // should they belong to the model being analysed. - std::map primaryExternalVariables; + std::unordered_map primaryExternalVariables; if (!mExternalVariables.empty()) { for (const auto &externalVariable : mExternalVariables) { @@ -2412,6 +2455,8 @@ void Analyser::AnalyserImpl::analyseModel(const ModelPtr &model) != primaryExternalVariable.second.end(); if (isVoi || (equivalentVariableCount > 1) || !hasPrimaryVariable) { + description.reserve(256 + 250 * equivalentVariableCount); + description += (equivalentVariableCount == 2) ? "Both " : ""; for (size_t i = 0; i < equivalentVariableCount; ++i) { @@ -2642,6 +2687,7 @@ void Analyser::AnalyserImpl::analyseModel(const ModelPtr &model) // Make sure that our equations are valid. AnalyserInternalVariablePtrs addedExternalVariables; + std::unordered_set addedExternalVariablesSet; AnalyserInternalEquationPtrs addedInternalEquations; AnalyserInternalEquationPtrs removedInternalEquations; auto nlaSystemIndex = MAX_SIZE_T; @@ -2655,13 +2701,21 @@ void Analyser::AnalyserImpl::analyseModel(const ModelPtr &model) if (internalEquation->mType == AnalyserInternalEquation::Type::NLA) { for (const auto &unknownVariable : internalEquation->mUnknownVariables) { if (unknownVariable->mIsExternalVariable - && (std::find(addedExternalVariables.begin(), addedExternalVariables.end(), unknownVariable) == addedExternalVariables.end())) { + && addedExternalVariablesSet.insert(unknownVariable.get()).second) { addedExternalVariables.push_back(unknownVariable); addedInternalEquations.push_back(AnalyserInternalEquation::create(unknownVariable)); } } internalEquation->mUnknownVariables.erase(std::remove_if(internalEquation->mUnknownVariables.begin(), internalEquation->mUnknownVariables.end(), isExternalVariable), internalEquation->mUnknownVariables.end()); + + // Rebuild our companion set. + + internalEquation->mUnknownVariablesSet.clear(); + + for (const auto &unknownVariable : internalEquation->mUnknownVariables) { + internalEquation->mUnknownVariablesSet.insert(unknownVariable.get()); + } } // Discard the equation if we have no unknown variables left. @@ -2695,7 +2749,7 @@ void Analyser::AnalyserImpl::analyseModel(const ModelPtr &model) AnalyserInternalVariablePtrs commonUnknownVariables; for (const auto &unknownVariable : internalEquation->mUnknownVariables) { - if (std::find(otherInternalEquation->mUnknownVariables.begin(), otherInternalEquation->mUnknownVariables.end(), unknownVariable) != otherInternalEquation->mUnknownVariables.end()) { + if (otherInternalEquation->mUnknownVariablesSet.count(unknownVariable.get()) != 0) { commonUnknownVariables.push_back(unknownVariable); } } @@ -2721,8 +2775,21 @@ void Analyser::AnalyserImpl::analyseModel(const ModelPtr &model) mInternalEquations.push_back(addedInternalEquation); } - for (const auto &removedInternalEquation : removedInternalEquations) { - mInternalEquations.erase(std::find(mInternalEquations.begin(), mInternalEquations.end(), removedInternalEquation)); + if (!removedInternalEquations.empty()) { + std::unordered_set removedInternalEquationsSet; + + removedInternalEquationsSet.reserve(removedInternalEquations.size()); + + for (const auto &removedInternalEquation : removedInternalEquations) { + removedInternalEquationsSet.insert(removedInternalEquation.get()); + } + + mInternalEquations.erase( + std::remove_if(mInternalEquations.begin(), mInternalEquations.end(), + [&removedInternalEquationsSet](const auto &removedInternalEquation) { + return removedInternalEquationsSet.count(removedInternalEquation.get()) != 0; + }), + mInternalEquations.end()); } // Confirm that equations that compute a variable-based constant are still @@ -2741,7 +2808,9 @@ void Analyser::AnalyserImpl::analyseModel(const ModelPtr &model) // having been marked as external). AnalyserInternalVariablePtrs underconstrainedVariables; + std::unordered_set underconstrainedVariablesSet; AnalyserInternalVariablePtrs overconstrainedVariables; + std::unordered_set overconstrainedVariablesSet; for (const auto &internalEquation : mInternalEquations) { switch (internalEquation->mType) { @@ -2772,7 +2841,7 @@ void Analyser::AnalyserImpl::analyseModel(const ModelPtr &model) // NLA system should be considered as underconstrained. for (const auto &unknownVariable : internalEquation->mUnknownVariables) { - if (std::find(underconstrainedVariables.begin(), underconstrainedVariables.end(), unknownVariable) == underconstrainedVariables.end()) { + if (underconstrainedVariablesSet.insert(unknownVariable.get()).second) { unknownVariable->mType = AnalyserInternalVariable::Type::UNDERCONSTRAINED; addInvalidVariableIssue(unknownVariable, Issue::ReferenceRule::ANALYSER_VARIABLE_UNDERCONSTRAINED); @@ -2785,7 +2854,7 @@ void Analyser::AnalyserImpl::analyseModel(const ModelPtr &model) // system should be considered as overconstrained. for (const auto &unknownVariable : internalEquation->mUnknownVariables) { - if (std::find(overconstrainedVariables.begin(), overconstrainedVariables.end(), unknownVariable) == overconstrainedVariables.end()) { + if (overconstrainedVariablesSet.insert(unknownVariable.get()).second) { unknownVariable->mType = AnalyserInternalVariable::Type::OVERCONSTRAINED; addInvalidVariableIssue(unknownVariable, Issue::ReferenceRule::ANALYSER_VARIABLE_OVERCONSTRAINED); @@ -2817,7 +2886,7 @@ void Analyser::AnalyserImpl::analyseModel(const ModelPtr &model) // Determine the type of our model. - auto hasNlaEquations = std::any_of(mInternalEquations.begin(), mInternalEquations.end(), [=](const auto &ie) { + auto hasNlaEquations = std::any_of(mInternalEquations.begin(), mInternalEquations.end(), [&](const auto &ie) { if (ie->mType == AnalyserInternalEquation::Type::NLA) { // Make sure that not all the variables involved in the NLA system // have been marked as external @@ -2861,7 +2930,7 @@ void Analyser::AnalyserImpl::analyseModel(const ModelPtr &model) // Create a mapping between our internal equations and our future equations // in the API. - std::map aie2aeMappings; + std::unordered_map aie2aeMappings; for (const auto &internalEquation : mInternalEquations) { aie2aeMappings.emplace(internalEquation, AnalyserEquation::AnalyserEquationImpl::create()); @@ -2871,7 +2940,7 @@ void Analyser::AnalyserImpl::analyseModel(const ModelPtr &model) // Note: start because we need to determine the type of our equations before we can make our internal variables // available through our API. - std::map aie2aetMappings; + std::unordered_map aie2aetMappings; for (const auto &internalEquation : mInternalEquations) { // Determine whether the equation is an external one. @@ -2924,8 +2993,8 @@ void Analyser::AnalyserImpl::analyseModel(const ModelPtr &model) // Make our internal variables available through our API. - std::map aiv2avMappings; - std::map v2avMappings; + std::unordered_map aiv2avMappings; + std::unordered_map v2avMappings; auto stateIndex = MAX_SIZE_T; auto constantIndex = MAX_SIZE_T; auto computedConstantIndex = MAX_SIZE_T; @@ -2972,11 +3041,12 @@ void Analyser::AnalyserImpl::analyseModel(const ModelPtr &model) auto isNlaEquation = false; for (const auto &internalEquation : mInternalEquations) { - if (std::find(internalEquation->mUnknownVariables.begin(), internalEquation->mUnknownVariables.end(), internalVariable) != internalEquation->mUnknownVariables.end()) { + if (internalEquation->mUnknownVariablesSet.count(internalVariable.get()) != 0) { equations.push_back(aie2aeMappings[internalEquation]); - if ((aie2aetMappings.find(internalEquation) != aie2aetMappings.end()) - && (aie2aetMappings[internalEquation] == AnalyserEquation::Type::NLA)) { + auto aetIt = aie2aetMappings.find(internalEquation); + + if ((aetIt != aie2aetMappings.end()) && (aetIt->second == AnalyserEquation::Type::NLA)) { isNlaEquation = true; } } @@ -3028,7 +3098,9 @@ void Analyser::AnalyserImpl::analyseModel(const ModelPtr &model) for (const auto &internalEquation : mInternalEquations) { // Make sure that the type of the equation is known. - if (aie2aetMappings.find(internalEquation) == aie2aetMappings.end()) { + auto aetIt = aie2aetMappings.find(internalEquation); + + if (aetIt == aie2aetMappings.end()) { continue; } @@ -3040,7 +3112,7 @@ void Analyser::AnalyserImpl::analyseModel(const ModelPtr &model) // Manipulate the equation, if needed. - auto equationType = aie2aetMappings[internalEquation]; + auto equationType = aetIt->second; switch (equationType) { case AnalyserEquation::Type::NLA: @@ -3082,13 +3154,14 @@ void Analyser::AnalyserImpl::analyseModel(const ModelPtr &model) } AnalyserEquationPtrs equationDependencies; + std::unordered_set seenAnalyserEquations; for (const auto &variableDependency : variableDependencies) { auto analyserVariable = v2avMappings[variableDependency]; if (analyserVariable != nullptr) { for (const auto &analyserEquation : analyserVariable->analyserEquations()) { - if (std::find(equationDependencies.begin(), equationDependencies.end(), analyserEquation) == equationDependencies.end()) { + if (seenAnalyserEquations.insert(analyserEquation.get()).second) { if (analyserVariable->type() == AnalyserVariable::Type::CONSTANT) { // This is a constant, so keep track of it in case it is untracked and in case we need to // generate some code for it. @@ -3160,7 +3233,7 @@ void Analyser::AnalyserImpl::analyseModel(const ModelPtr &model) // Note: obviously, this can only be done once all our equations are ready. for (const auto &analyserEquation : mAnalyserModel->mPimpl->mAnalyserEquations) { - AnalyserEquationPtrs checkedEquations; + std::unordered_set checkedEquations; analyserEquation->mPimpl->mIsStateRateBased = isStateRateBased(analyserEquation, checkedEquations); } @@ -3168,14 +3241,14 @@ void Analyser::AnalyserImpl::analyseModel(const ModelPtr &model) AnalyserExternalVariablePtrs::const_iterator Analyser::AnalyserImpl::findExternalVariable(const VariablePtr &variable) const { - return std::find_if(mExternalVariables.begin(), mExternalVariables.end(), [=](const auto &ev) { + return std::find_if(mExternalVariables.begin(), mExternalVariables.end(), [&](const auto &ev) { return ev->variable() == variable; }); } AnalyserExternalVariablePtrs::const_iterator Analyser::AnalyserImpl::findExternalVariable(const AnalyserExternalVariablePtr &externalVariable) const { - return std::find_if(mExternalVariables.begin(), mExternalVariables.end(), [=](const auto &ev) { + return std::find_if(mExternalVariables.begin(), mExternalVariables.end(), [&](const auto &ev) { return ev == externalVariable; }); } diff --git a/src/analyser_p.h b/src/analyser_p.h index f888861de..515c2745c 100644 --- a/src/analyser_p.h +++ b/src/analyser_p.h @@ -17,6 +17,8 @@ limitations under the License. #include "libcellml/generatorprofile.h" #include "libcellml/issue.h" +#include + #include "analysermodel_p.h" #include "internaltypes.h" #include "logger_p.h" @@ -96,9 +98,12 @@ struct AnalyserInternalEquation ComponentPtr mComponent; AnalyserInternalVariablePtrs mVariables; + std::unordered_set mVariablesSet; AnalyserInternalVariablePtrs mStateVariables; + std::unordered_set mStateVariablesSet; AnalyserInternalVariablePtrs mAllVariables; AnalyserInternalVariablePtrs mUnknownVariables; + std::unordered_set mUnknownVariablesSet; size_t mNlaSystemIndex = MAX_SIZE_T; AnalyserInternalEquationWeakPtrs mNlaSiblings; @@ -160,12 +165,13 @@ class Analyser::AnalyserImpl: public Logger::LoggerImpl AnalyserExternalVariablePtrs mExternalVariables; AnalyserInternalVariablePtrs mInternalVariables; + std::unordered_map mInternalVariableCache; AnalyserInternalEquationPtrs mInternalEquations; GeneratorProfilePtr mGeneratorProfile = GeneratorProfile::create(); - std::map mStandardUnits; - std::map mCiCnUnits; + std::unordered_map mStandardUnits; + std::unordered_map mCiCnUnits; AnalyserImpl(); @@ -181,8 +187,8 @@ class Analyser::AnalyserImpl: public Logger::LoggerImpl void analyseComponent(const ComponentPtr &component); void analyseComponentVariables(const ComponentPtr &component); - void equivalentVariables(const VariablePtr &variable, - VariablePtrs &equivalentVariables) const; + void equivalentVariables(const VariablePtr &variable, VariablePtrs &equivalentVariables, + std::unordered_set &seen) const; VariablePtrs equivalentVariables(const VariablePtr &variable) const; void analyseEquationAst(const AnalyserEquationAstPtr &ast); @@ -251,7 +257,7 @@ class Analyser::AnalyserImpl: public Logger::LoggerImpl static bool isExternalVariable(const AnalyserInternalVariablePtr &variable); bool isStateRateBased(const AnalyserEquationPtr &analyserEquation, - AnalyserEquationPtrs &checkedEquations); + std::unordered_set &checkedEquations); void addInvalidVariableIssue(const AnalyserInternalVariablePtr &variable, Issue::ReferenceRule referenceRule); diff --git a/src/analyserequation.cpp b/src/analyserequation.cpp index 50959cd40..17130a4b3 100644 --- a/src/analyserequation.cpp +++ b/src/analyserequation.cpp @@ -93,6 +93,8 @@ std::vector AnalyserEquation::dependencies() const { std::vector res; + res.reserve(mPimpl->mDependencies.size()); + for (const auto &dependency : mPimpl->mDependencies) { res.push_back(dependency.lock()); } @@ -123,6 +125,8 @@ std::vector AnalyserEquation::nlaSiblings() const { std::vector res; + res.reserve(mPimpl->mNlaSiblings.size()); + for (const auto &nlaSibling : mPimpl->mNlaSiblings) { res.push_back(nlaSibling.lock()); } @@ -149,7 +153,7 @@ size_t AnalyserEquation::stateCount() const return mPimpl->mStates.size(); } -std::vector AnalyserEquation::states() const +const std::vector &AnalyserEquation::states() const { return mPimpl->mStates; } @@ -168,7 +172,7 @@ size_t AnalyserEquation::computedConstantCount() const return mPimpl->mComputedConstants.size(); } -std::vector AnalyserEquation::computedConstants() const +const std::vector &AnalyserEquation::computedConstants() const { return mPimpl->mComputedConstants; } @@ -187,7 +191,7 @@ size_t AnalyserEquation::algebraicVariableCount() const return mPimpl->mAlgebraicVariables.size(); } -std::vector AnalyserEquation::algebraicVariables() const +const std::vector &AnalyserEquation::algebraicVariables() const { return mPimpl->mAlgebraicVariables; } @@ -206,7 +210,7 @@ size_t AnalyserEquation::externalVariableCount() const return mPimpl->mExternalVariables.size(); } -std::vector AnalyserEquation::externalVariables() const +const std::vector &AnalyserEquation::externalVariables() const { return mPimpl->mExternalVariables; } diff --git a/src/analyserequationast.cpp b/src/analyserequationast.cpp index f543f766f..5cbc175c6 100644 --- a/src/analyserequationast.cpp +++ b/src/analyserequationast.cpp @@ -170,7 +170,7 @@ void AnalyserEquationAst::setType(Type type) mPimpl->mType = type; } -std::string AnalyserEquationAst::value() const +const std::string &AnalyserEquationAst::value() const { return mPimpl->mValue; } diff --git a/src/analyserexternalvariable.cpp b/src/analyserexternalvariable.cpp index 41a9606ff..67ef5bdf1 100644 --- a/src/analyserexternalvariable.cpp +++ b/src/analyserexternalvariable.cpp @@ -31,7 +31,7 @@ std::vector::iterator AnalyserExternalVariable::AnalyserExternalVar const std::string &componentName, const std::string &variableName) { - return std::find_if(mDependencies.begin(), mDependencies.end(), [=](const auto &v) { + return std::find_if(mDependencies.begin(), mDependencies.end(), [&](const auto &v) { return (owningModel(v) == model) && (owningComponent(v)->name() == componentName) && (v->name() == variableName); @@ -40,7 +40,7 @@ std::vector::iterator AnalyserExternalVariable::AnalyserExternalVar std::vector::iterator AnalyserExternalVariable::AnalyserExternalVariableImpl::findDependency(const VariablePtr &variable) { - return std::find_if(mDependencies.begin(), mDependencies.end(), [=](const auto &v) { + return std::find_if(mDependencies.begin(), mDependencies.end(), [&](const auto &v) { return v == variable; }); } @@ -155,7 +155,7 @@ VariablePtr AnalyserExternalVariable::dependency(const ModelPtr &model, nullptr; } -std::vector AnalyserExternalVariable::dependencies() const +const std::vector &AnalyserExternalVariable::dependencies() const { return mPimpl->mDependencies; } diff --git a/src/analysermodel.cpp b/src/analysermodel.cpp index fe6c16ca7..2fb51b48e 100644 --- a/src/analysermodel.cpp +++ b/src/analysermodel.cpp @@ -23,6 +23,9 @@ limitations under the License. namespace libcellml { +static const std::vector NO_ANALYSER_EQUATION; +static const std::vector NO_ANALYSER_VARIABLE; + AnalyserModelPtr AnalyserModel::AnalyserModelImpl::create(const ModelPtr &model) { return std::shared_ptr {new AnalyserModel(model)}; @@ -104,10 +107,10 @@ size_t AnalyserModel::stateCount() const return mPimpl->mStates.size(); } -std::vector AnalyserModel::states() const +const std::vector &AnalyserModel::states() const { if (!isValid()) { - return {}; + return NO_ANALYSER_VARIABLE; } return mPimpl->mStates; @@ -132,10 +135,10 @@ size_t AnalyserModel::constantCount() const return mPimpl->mConstants.size(); } -std::vector AnalyserModel::constants() const +const std::vector &AnalyserModel::constants() const { if (!isValid()) { - return {}; + return NO_ANALYSER_VARIABLE; } return mPimpl->mConstants; @@ -159,10 +162,10 @@ size_t AnalyserModel::computedConstantCount() const return mPimpl->mComputedConstants.size(); } -std::vector AnalyserModel::computedConstants() const +const std::vector &AnalyserModel::computedConstants() const { if (!isValid()) { - return {}; + return NO_ANALYSER_VARIABLE; } return mPimpl->mComputedConstants; @@ -186,10 +189,10 @@ size_t AnalyserModel::algebraicVariableCount() const return mPimpl->mAlgebraicVariables.size(); } -std::vector AnalyserModel::algebraicVariables() const +const std::vector &AnalyserModel::algebraicVariables() const { if (!isValid()) { - return {}; + return NO_ANALYSER_VARIABLE; } return mPimpl->mAlgebraicVariables; @@ -213,10 +216,10 @@ size_t AnalyserModel::externalVariableCount() const return mPimpl->mExternalVariables.size(); } -std::vector AnalyserModel::externalVariables() const +const std::vector &AnalyserModel::externalVariables() const { if (!isValid()) { - return {}; + return NO_ANALYSER_VARIABLE; } return mPimpl->mExternalVariables; @@ -237,8 +240,20 @@ AnalyserVariablePtr AnalyserModel::analyserVariable(const VariablePtr &variable) return {}; } + // Check the cache first. + + auto analyserVariableIt = mPimpl->mAnalyserVariables.find(variable.get()); + + if (analyserVariableIt != mPimpl->mAnalyserVariables.end()) { + return analyserVariableIt->second; + } + + // Not in the cache, so do the equivalence-based search. + for (const auto &analyserVariable : analyserVariables(shared_from_this())) { if (areEquivalentVariables(variable, analyserVariable->variable())) { + mPimpl->mAnalyserVariables.emplace(variable.get(), analyserVariable); + return analyserVariable; } } @@ -255,10 +270,10 @@ size_t AnalyserModel::analyserEquationCount() const return mPimpl->mAnalyserEquations.size(); } -std::vector AnalyserModel::analyserEquations() const +const std::vector &AnalyserModel::analyserEquations() const { if (!isValid()) { - return {}; + return NO_ANALYSER_EQUATION; } return mPimpl->mAnalyserEquations; diff --git a/src/analysermodel_p.h b/src/analysermodel_p.h index 5c557b88a..1b731fadd 100644 --- a/src/analysermodel_p.h +++ b/src/analysermodel_p.h @@ -66,6 +66,8 @@ struct AnalyserModel::AnalyserModelImpl } }; + mutable std::unordered_map mAnalyserVariables; + struct VariableKeyPairHash { size_t operator()(const VariableKeyPair &pair) const diff --git a/src/analyservariable.cpp b/src/analyservariable.cpp index 1886f2b67..be7e05afc 100644 --- a/src/analyservariable.cpp +++ b/src/analyservariable.cpp @@ -120,6 +120,8 @@ std::vector AnalyserVariable::analyserEquations() const std::vector res; + res.reserve(mPimpl->mAnalyserEquations.size()); + for (const auto &analyserEquation : mPimpl->mAnalyserEquations) { res.push_back(analyserEquation.lock()); } diff --git a/src/annotator.cpp b/src/annotator.cpp index 715997d9a..0fe76a9e8 100644 --- a/src/annotator.cpp +++ b/src/annotator.cpp @@ -17,6 +17,7 @@ limitations under the License. #include "libcellml/annotator.h" #include +#include #include #include @@ -236,13 +237,16 @@ void Annotator::AnnotatorImpl::listComponentIdsAndItems(const ComponentPtr &comp if (idList.count(id) != 0) { // Get the range of items with this identifier: auto rangePair = idList.equal_range(id); + auto compEquiv = owningComponent(equivalentVariable); + auto compVar = owningComponent(variable); for (auto it = rangePair.first; it != rangePair.second; ++it) { // Make sure it's also a CONNECTION item. if (it->second->type() == CellmlElementType::CONNECTION) { auto testPair = it->second->variablePair(); - if ((owningComponent(testPair->variable1()) == owningComponent(equivalentVariable)) && (owningComponent(testPair->variable2()) == owningComponent(variable))) { - found = true; - } else if ((owningComponent(testPair->variable2()) == owningComponent(equivalentVariable)) && (owningComponent(testPair->variable1()) == owningComponent(variable))) { + auto compTest1 = owningComponent(testPair->variable1()); + auto compTest2 = owningComponent(testPair->variable2()); + if (((compTest1 == compEquiv) && (compTest2 == compVar)) + || ((compTest2 == compEquiv) && (compTest1 == compVar))) { found = true; } } @@ -352,7 +356,7 @@ AnyCellmlElementPtr Annotator::AnnotatorImpl::convertToWeak(const AnyCellmlEleme converted->mPimpl->mType = type; - switch (item->type()) { + switch (type) { case CellmlElementType::COMPONENT: case CellmlElementType::COMPONENT_REF: { ComponentWeakPtr weakComponent = item->component(); @@ -517,7 +521,7 @@ void Annotator::AnnotatorImpl::addIssueInvalidArgument(CellmlElementType type) void Annotator::AnnotatorImpl::addIssueNonUnique(const std::string &id) { auto issue = Issue::IssueImpl::create(); - issue->mPimpl->setDescription("The identifier '" + id + "' occurs " + std::to_string(mIdList.count(id)) + " times in the model so a unique item cannot be located."); + issue->mPimpl->setDescription("The identifier '" + id + "' occurs " + std::format("{}", mIdList.count(id)) + " times in the model so a unique item cannot be located."); issue->mPimpl->setLevel(Issue::Level::WARNING); issue->mPimpl->setReferenceRule(Issue::ReferenceRule::ANNOTATOR_ID_NOT_UNIQUE); addIssue(issue); @@ -1417,20 +1421,26 @@ size_t Annotator::itemCount(const std::string &id) void Annotator::AnnotatorImpl::doUpdateComponentHash(const ComponentPtr &component, std::string &idsString) { - for (size_t i = 0; i < component->variableCount(); ++i) { - idsString += "v=" + std::to_string(i) + component->variable(i)->id(); + const auto variableCount = component->variableCount(); + const auto resetCount = component->resetCount(); + const auto componentCount = component->componentCount(); + + idsString.reserve(idsString.size() + 24 * (variableCount + resetCount + componentCount)); + + for (size_t i = 0; i < variableCount; ++i) { + idsString += "v=" + std::format("{}", i) + component->variable(i)->id(); } - for (size_t i = 0; i < component->resetCount(); ++i) { + for (size_t i = 0; i < resetCount; ++i) { auto reset = component->reset(i); - idsString += "r=" + std::to_string(i) + reset->id() + "rv=" + reset->resetValueId() + "tv=" + reset->testValueId(); + idsString += "r=" + std::format("{}", i) + reset->id() + "rv=" + reset->resetValueId() + "tv=" + reset->testValueId(); } // Note that MathML identifiers are not yet included. - for (size_t i = 0; i < component->componentCount(); ++i) { + for (size_t i = 0; i < componentCount; ++i) { auto child = component->component(i); - idsString += "c=" + std::to_string(i) + child->id() + "ce=" + child->encapsulationId(); + idsString += "c=" + std::format("{}", i) + child->id() + "ce=" + child->encapsulationId(); doUpdateComponentHash(child, idsString); } } @@ -1443,26 +1453,27 @@ size_t Annotator::AnnotatorImpl::generateHash() if (model != nullptr) { std::string idsString; size_t i; - idsString += "m=" + model->id() + "me=" + model->encapsulationId(); auto importSources = getAllImportSources(model); + idsString.reserve(64 + 32 * (importSources.size() + model->unitsCount() + model->componentCount())); + idsString += "m=" + model->id() + "me=" + model->encapsulationId(); i = 0; for (auto &importSource : importSources) { - idsString += "i=" + std::to_string(++i) + importSource->id(); + idsString += "i=" + std::format("{}", ++i) + importSource->id(); } for (i = 0; i < model->unitsCount(); ++i) { auto units = model->units(i); - idsString += "U=" + std::to_string(i) + units->id(); + idsString += "U=" + std::format("{}", i) + units->id(); for (size_t j = 0; j < units->unitCount(); ++j) { - idsString += "u=" + std::to_string(j) + units->unitId(j); + idsString += "u=" + std::format("{}", j) + units->unitId(j); } } for (i = 0; i < model->componentCount(); ++i) { auto component = model->component(i); - idsString += "c=" + std::to_string(i) + component->id(); - idsString += "cr=" + std::to_string(i) + component->encapsulationId(); + idsString += "c=" + std::format("{}", i) + component->id(); + idsString += "cr=" + std::format("{}", i) + component->encapsulationId(); doUpdateComponentHash(component, idsString); } diff --git a/src/api/libcellml/analyserequation.h b/src/api/libcellml/analyserequation.h index 7fcb8d367..6cf861e20 100644 --- a/src/api/libcellml/analyserequation.h +++ b/src/api/libcellml/analyserequation.h @@ -185,7 +185,7 @@ class LIBCELLML_EXPORT AnalyserEquation * * @return The states as a @c std::vector. */ - std::vector states() const; + const std::vector &states() const; /** * @brief Get the state, at @p index, computed by this @ref AnalyserEquation. @@ -214,7 +214,7 @@ class LIBCELLML_EXPORT AnalyserEquation * * @return The computed constants as a @c std::vector. */ - std::vector computedConstants() const; + const std::vector &computedConstants() const; /** * @brief Get the computed constant, at @p index, computed by this @ref AnalyserEquation. @@ -243,7 +243,7 @@ class LIBCELLML_EXPORT AnalyserEquation * * @return The algebraic variables as a @c std::vector. */ - std::vector algebraicVariables() const; + const std::vector &algebraicVariables() const; /** * @brief Get the algebraic variable, at @p index, computed by this @ref AnalyserEquation. @@ -272,7 +272,7 @@ class LIBCELLML_EXPORT AnalyserEquation * * @return The external variables as a @c std::vector. */ - std::vector externalVariables() const; + const std::vector &externalVariables() const; /** * @brief Get the external variable, at @p index, computed by this @ref AnalyserEquation. diff --git a/src/api/libcellml/analyserequationast.h b/src/api/libcellml/analyserequationast.h index 2467de112..7ec140adb 100644 --- a/src/api/libcellml/analyserequationast.h +++ b/src/api/libcellml/analyserequationast.h @@ -190,7 +190,7 @@ class LIBCELLML_EXPORT AnalyserEquationAst * * @return The value. */ - std::string value() const; + const std::string &value() const; /** * @brief Set the value for this @ref AnalyserEquationAst. diff --git a/src/api/libcellml/analyserexternalvariable.h b/src/api/libcellml/analyserexternalvariable.h index 2f37eca12..bbcae50b0 100644 --- a/src/api/libcellml/analyserexternalvariable.h +++ b/src/api/libcellml/analyserexternalvariable.h @@ -227,7 +227,7 @@ class LIBCELLML_EXPORT AnalyserExternalVariable * * @return The dependencies as a @c std::vector. */ - std::vector dependencies() const; + const std::vector &dependencies() const; /** * @brief Get the number of dependencies of this @ref AnalyserExternalVariable. diff --git a/src/api/libcellml/analysermodel.h b/src/api/libcellml/analysermodel.h index 12806e676..d94695273 100644 --- a/src/api/libcellml/analysermodel.h +++ b/src/api/libcellml/analysermodel.h @@ -137,7 +137,7 @@ class LIBCELLML_EXPORT AnalyserModel * * @return The states as a @c std::vector. */ - std::vector states() const; + const std::vector &states() const; /** * @brief Get the state at @p index. @@ -167,7 +167,7 @@ class LIBCELLML_EXPORT AnalyserModel * * @return The constants as a @c std::vector. */ - std::vector constants() const; + const std::vector &constants() const; /** * @brief Get the constant at @p index. @@ -197,7 +197,7 @@ class LIBCELLML_EXPORT AnalyserModel * * @return The computed constants as a @c std::vector. */ - std::vector computedConstants() const; + const std::vector &computedConstants() const; /** * @brief Get the computed constant at @p index. @@ -227,7 +227,7 @@ class LIBCELLML_EXPORT AnalyserModel * * @return The algebraic variables as a @c std::vector. */ - std::vector algebraicVariables() const; + const std::vector &algebraicVariables() const; /** * @brief Get the algebraic variable at @p index. @@ -257,7 +257,7 @@ class LIBCELLML_EXPORT AnalyserModel * * @return The external variables as a @c std::vector. */ - std::vector externalVariables() const; + const std::vector &externalVariables() const; /** * @brief Get the external variable at @p index. @@ -298,7 +298,7 @@ class LIBCELLML_EXPORT AnalyserModel * * @return The analyser equations as a @c std::vector. */ - std::vector analyserEquations() const; + const std::vector &analyserEquations() const; /** * @brief Get the analyser equation at @p index. diff --git a/src/api/libcellml/component.h b/src/api/libcellml/component.h index 6bc45d969..54e1356c9 100644 --- a/src/api/libcellml/component.h +++ b/src/api/libcellml/component.h @@ -107,7 +107,7 @@ class LIBCELLML_EXPORT Component: public ComponentEntity, public ImportedEntity * * @return @c std::string math for this component. */ - std::string math() const; + const std::string &math() const; /** * @brief Set the math string for this component. diff --git a/src/api/libcellml/componententity.h b/src/api/libcellml/componententity.h index 142604f70..48e8df9e3 100644 --- a/src/api/libcellml/componententity.h +++ b/src/api/libcellml/componententity.h @@ -289,7 +289,7 @@ class LIBCELLML_EXPORT ComponentEntity: public NamedEntity * * @return The @c std::string of the encapsulation identifier. */ - std::string encapsulationId() const; + const std::string &encapsulationId() const; /** * @brief Remove the encapsulation identifier for this entity. diff --git a/src/api/libcellml/entity.h b/src/api/libcellml/entity.h index 70c694add..86eb1e542 100644 --- a/src/api/libcellml/entity.h +++ b/src/api/libcellml/entity.h @@ -56,7 +56,7 @@ class LIBCELLML_EXPORT Entity * * @return The @c std::string document identifier for this entity. */ - std::string id() const; + const std::string &id() const; /** * @brief Remove the identifier for this entity. diff --git a/src/api/libcellml/generatorprofile.h b/src/api/libcellml/generatorprofile.h index 9d40971f8..01874878b 100644 --- a/src/api/libcellml/generatorprofile.h +++ b/src/api/libcellml/generatorprofile.h @@ -129,7 +129,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string representing the MathML "equality" operator. */ - std::string equalityString() const; + const std::string &equalityString() const; /** * @brief Set the @c std::string representing the MathML "equality" @@ -152,7 +152,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string representing the MathML "equal to" operator. */ - std::string eqString() const; + const std::string &eqString() const; /** * @brief Set the @c std::string representing the MathML "equal to" @@ -175,7 +175,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string representing the MathML "not equal to" * operator. */ - std::string neqString() const; + const std::string &neqString() const; /** * @brief Set the @c std::string representing the MathML "not equal to" @@ -196,7 +196,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string representing the MathML "less than" operator. */ - std::string ltString() const; + const std::string <String() const; /** * @brief Set the @c std::string representing the MathML "less than" @@ -219,7 +219,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string representing the MathML "less than or equal * to" operator. */ - std::string leqString() const; + const std::string &leqString() const; /** * @brief Set the @c std::string representing the MathML "less than or @@ -243,7 +243,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string representing the MathML "greater than" * operator. */ - std::string gtString() const; + const std::string >String() const; /** * @brief Set the @c std::string representing the MathML "greater than" @@ -266,7 +266,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string representing the MathML "greater than or * equal to" operator. */ - std::string geqString() const; + const std::string &geqString() const; /** * @brief Set the @c std::string representing the MathML "greater than or @@ -287,7 +287,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string representing the MathML "and" operator. */ - std::string andString() const; + const std::string &andString() const; /** * @brief Set the @c std::string representing the MathML "and" operator. @@ -306,7 +306,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string representing the MathML "or" operator. */ - std::string orString() const; + const std::string &orString() const; /** * @brief Set the @c std::string representing the MathML "or" operator. @@ -327,7 +327,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string representing the MathML "exclusive or" * operator. */ - std::string xorString() const; + const std::string &xorString() const; /** * @brief Set the @c std::string representing the MathML "exclusive or" @@ -347,7 +347,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string representing the MathML "not" operator. */ - std::string notString() const; + const std::string ¬String() const; /** * @brief Set the @c std::string representing the MathML "not" operator. @@ -579,7 +579,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string representing the MathML "plus" operator. */ - std::string plusString() const; + const std::string &plusString() const; /** * @brief Set the @c std::string representing the MathML "plus" operator. @@ -598,7 +598,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string representing the MathML "minus" operator. */ - std::string minusString() const; + const std::string &minusString() const; /** * @brief Set the @c std::string representing the MathML "minus" operator. @@ -617,7 +617,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string representing the MathML "times" operator. */ - std::string timesString() const; + const std::string ×String() const; /** * @brief Set the @c std::string representing the MathML "times" operator. @@ -636,7 +636,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string representing the MathML "divide" operator. */ - std::string divideString() const; + const std::string ÷String() const; /** * @brief Set the @c std::string representing the MathML "divide" operator. @@ -658,7 +658,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string representing the MathML "power" operator or * function. */ - std::string powerString() const; + const std::string &powerString() const; /** * @brief Set the @c std::string representing the MathML "power" operator or @@ -681,7 +681,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string representing the MathML "square root" * function. */ - std::string squareRootString() const; + const std::string &squareRootString() const; /** * @brief Set the @c std::string representing the MathML "square root" @@ -701,7 +701,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string representing the MathML "square" function. */ - std::string squareString() const; + const std::string &squareString() const; /** * @brief Set the @c std::string representing the MathML "square" function. @@ -723,7 +723,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string representing the MathML "absolute value" * function. */ - std::string absoluteValueString() const; + const std::string &absoluteValueString() const; /** * @brief Set the @c std::string representing the MathML "absolute value" @@ -746,7 +746,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string representing the MathML "exponential" * function. */ - std::string exponentialString() const; + const std::string &exponentialString() const; /** * @brief Set the @c std::string representing the MathML "exponential" @@ -769,7 +769,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string representing the MathML "natural logarithm" * function. */ - std::string naturalLogarithmString() const; + const std::string &naturalLogarithmString() const; /** * @brief Set the @c std::string representing the MathML "natural logarithm" @@ -793,7 +793,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string representing the MathML "common logarithm" * function. */ - std::string commonLogarithmString() const; + const std::string &commonLogarithmString() const; /** * @brief Set the @c std::string representing the MathML "common logarithm" @@ -814,7 +814,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string representing the MathML "ceiling" function. */ - std::string ceilingString() const; + const std::string &ceilingString() const; /** * @brief Set the @c std::string representing the MathML "ceiling" function. @@ -833,7 +833,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string representing the MathML "floor" function. */ - std::string floorString() const; + const std::string &floorString() const; /** * @brief Set the @c std::string representing the MathML "floor" function. @@ -852,7 +852,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string representing the MathML "minimum" function. */ - std::string minString() const; + const std::string &minString() const; /** * @brief Set the @c std::string representing the MathML "minimum" function. @@ -871,7 +871,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string representing the MathML "maximum" function. */ - std::string maxString() const; + const std::string &maxString() const; /** * @brief Set the @c std::string representing the MathML "maximum" function. @@ -891,7 +891,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string representing the MathML "remainder" function. */ - std::string remString() const; + const std::string &remString() const; /** * @brief Set the @c std::string representing the MathML "remainder" @@ -933,7 +933,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string representing the MathML "sine" function. */ - std::string sinString() const; + const std::string &sinString() const; /** * @brief Set the @c std::string representing the MathML "sine" function. @@ -952,7 +952,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string representing the MathML "cosine" function. */ - std::string cosString() const; + const std::string &cosString() const; /** * @brief Set the @c std::string representing the MathML "cosine" function. @@ -971,7 +971,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string representing the MathML "tangent" function. */ - std::string tanString() const; + const std::string &tanString() const; /** * @brief Set the @c std::string representing the MathML "tangent" function. @@ -990,7 +990,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string representing the MathML "secant" function. */ - std::string secString() const; + const std::string &secString() const; /** * @brief Set the @c std::string representing the MathML "secant" function. @@ -1010,7 +1010,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string representing the MathML "cosecant" function. */ - std::string cscString() const; + const std::string &cscString() const; /** * @brief Set the @c std::string representing the MathML "cosecant" @@ -1031,7 +1031,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string representing the MathML "cotangent" function. */ - std::string cotString() const; + const std::string &cotString() const; /** * @brief Set the @c std::string representing the MathML "cotangent" @@ -1054,7 +1054,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string representing the MathML "hyperbolic sine" * function. */ - std::string sinhString() const; + const std::string &sinhString() const; /** * @brief Set the @c std::string representing the MathML "hyperbolic sine" @@ -1078,7 +1078,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string representing the MathML "hyperbolic cosine" * function. */ - std::string coshString() const; + const std::string &coshString() const; /** * @brief Set the @c std::string representing the MathML "hyperbolic cosine" @@ -1102,7 +1102,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string representing the MathML "hyperbolic tangent" * function. */ - std::string tanhString() const; + const std::string &tanhString() const; /** * @brief Set the @c std::string representing the MathML "hyperbolic @@ -1126,7 +1126,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string representing the MathML "hyperbolic secant" * function. */ - std::string sechString() const; + const std::string &sechString() const; /** * @brief Set the @c std::string representing the MathML "hyperbolic secant" @@ -1150,7 +1150,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string representing the MathML "hyperbolic cosecant" * function. */ - std::string cschString() const; + const std::string &cschString() const; /** * @brief Set the @c std::string representing the MathML "hyperbolic @@ -1174,7 +1174,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string representing the MathML "hyperbolic cotangent" * function. */ - std::string cothString() const; + const std::string &cothString() const; /** * @brief Set the @c std::string representing the MathML "hyperbolic @@ -1196,7 +1196,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string representing the MathML "arc sine" function. */ - std::string asinString() const; + const std::string &asinString() const; /** * @brief Set the @c std::string representing the MathML "arc sine" @@ -1217,7 +1217,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string representing the MathML "arc cosine" function. */ - std::string acosString() const; + const std::string &acosString() const; /** * @brief Set the @c std::string representing the MathML "arc cosine" @@ -1239,7 +1239,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string representing the MathML "arc tangent" * function. */ - std::string atanString() const; + const std::string &atanString() const; /** * @brief Set the @c std::string representing the MathML "arc tangent" @@ -1260,7 +1260,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string representing the MathML "arc secant" function. */ - std::string asecString() const; + const std::string &asecString() const; /** * @brief Set the @c std::string representing the MathML "arc secant" @@ -1283,7 +1283,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string representing the MathML "arc cosecant" * function. */ - std::string acscString() const; + const std::string &acscString() const; /** * @brief Set the @c std::string representing the MathML "arc cosecant" @@ -1306,7 +1306,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string representing the MathML "arc cotangent" * function. */ - std::string acotString() const; + const std::string &acotString() const; /** * @brief Set the @c std::string representing the MathML "arc cotangent" @@ -1329,7 +1329,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string representing the MathML "arc hyperbolic sine" * function. */ - std::string asinhString() const; + const std::string &asinhString() const; /** * @brief Set the @c std::string representing the MathML "arc hyperbolic @@ -1353,7 +1353,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string representing the MathML "arc hyperbolic * cosine" function. */ - std::string acoshString() const; + const std::string &acoshString() const; /** * @brief Set the @c std::string representing the MathML "arc hyperbolic @@ -1377,7 +1377,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string representing the MathML "arc hyperbolic * tangent" function. */ - std::string atanhString() const; + const std::string &atanhString() const; /** * @brief Set the @c std::string representing the MathML "arc hyperbolic @@ -1401,7 +1401,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string representing the MathML "arc hyperbolic * secant" function. */ - std::string asechString() const; + const std::string &asechString() const; /** * @brief Set the @c std::string representing the MathML "arc hyperbolic @@ -1425,7 +1425,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string representing the MathML "arc hyperbolic * cosecant" function. */ - std::string acschString() const; + const std::string &acschString() const; /** * @brief Set the @c std::string representing the MathML "arc hyperbolic @@ -1449,7 +1449,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string representing the MathML "arc hyperbolic * cotangent" function. */ - std::string acothString() const; + const std::string &acothString() const; /** * @brief Set the @c std::string representing the MathML "arc hyperbolic @@ -1475,7 +1475,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string representing the MathML "if" part of a * "conditional" statement or operator. */ - std::string conditionalOperatorIfString() const; + const std::string &conditionalOperatorIfString() const; /** * @brief Set the @c std::string representing the MathML "if" part of a @@ -1499,7 +1499,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string representing the MathML "else" part of a * "conditional" statement or operator. */ - std::string conditionalOperatorElseString() const; + const std::string &conditionalOperatorElseString() const; /** * @brief Set the @c std::string representing the MathML "else" part of a @@ -1523,7 +1523,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string representing the MathML "if" part of a * "piecewise" statement. */ - std::string piecewiseIfString() const; + const std::string &piecewiseIfString() const; /** * @brief Set the @c std::string representing the MathML "if" part of a @@ -1547,7 +1547,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string representing the MathML "else" part of a * "piecewise" statement. */ - std::string piecewiseElseString() const; + const std::string &piecewiseElseString() const; /** * @brief Set the @c std::string representing the MathML "else" part of a @@ -1590,7 +1590,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string representing the MathML "true" boolean. */ - std::string trueString() const; + const std::string &trueString() const; /** * @brief Set the @c std::string representing the MathML "true" boolean. @@ -1609,7 +1609,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string representing the MathML "false" boolean. */ - std::string falseString() const; + const std::string &falseString() const; /** * @brief Set the @c std::string representing the MathML "false" boolean. @@ -1628,7 +1628,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string representing the MathML "Euler's number". */ - std::string eString() const; + const std::string &eString() const; /** * @brief Set the @c std::string representing the MathML "Euler's number". @@ -1647,7 +1647,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string representing the MathML "Ï€" constant. */ - std::string piString() const; + const std::string &piString() const; /** * @brief Set the @c std::string representing the MathML "Ï€" constant. @@ -1665,7 +1665,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string representing the MathML "infinity" value. */ - std::string infString() const; + const std::string &infString() const; /** * @brief Set the @c std::string representing the MathML "infinity" value. @@ -1685,7 +1685,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string representing the MathML "not-a-number" value. */ - std::string nanString() const; + const std::string &nanString() const; /** * @brief Set the @c std::string representing the MathML "not-a-number" @@ -1707,7 +1707,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for the "equal to" function implementation. */ - std::string eqFunctionString() const; + const std::string &eqFunctionString() const; /** * @brief Set the @c std::string for the "equal to" function implementation. @@ -1728,7 +1728,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the "not equal to" function * implementation. */ - std::string neqFunctionString() const; + const std::string &neqFunctionString() const; /** * @brief Set the @c std::string for the "not equal to" function @@ -1749,7 +1749,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for the "less than" function implementation. */ - std::string ltFunctionString() const; + const std::string <FunctionString() const; /** * @brief Set the @c std::string for the "less than" function @@ -1772,7 +1772,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the "less than or equal to" function * implementation. */ - std::string leqFunctionString() const; + const std::string &leqFunctionString() const; /** * @brief Set the @c std::string for the "less than or equal to" function @@ -1795,7 +1795,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the "greater than" function * implementation. */ - std::string gtFunctionString() const; + const std::string >FunctionString() const; /** * @brief Set the @c std::string for the "greater than" function @@ -1818,7 +1818,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the "greater than or equal to" function * implementation. */ - std::string geqFunctionString() const; + const std::string &geqFunctionString() const; /** * @brief Set the @c std::string for the "greater than or equal to" function @@ -1839,7 +1839,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for the "and" function implementation. */ - std::string andFunctionString() const; + const std::string &andFunctionString() const; /** * @brief Set the @c std::string for the "and" function implementation. @@ -1858,7 +1858,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for the "or" function implementation. */ - std::string orFunctionString() const; + const std::string &orFunctionString() const; /** * @brief Set the @c std::string for the "or" function implementation. @@ -1879,7 +1879,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the "exclusive or" function * implementation. */ - std::string xorFunctionString() const; + const std::string &xorFunctionString() const; /** * @brief Set the @c std::string for the "exclusive or" function @@ -1899,7 +1899,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for the "not" function implementation. */ - std::string notFunctionString() const; + const std::string ¬FunctionString() const; /** * @brief Set the @c std::string for the "not" function implementation. @@ -1918,7 +1918,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for the "minimum" function implementation. */ - std::string minFunctionString() const; + const std::string &minFunctionString() const; /** * @brief Set the @c std::string for the "minimum" function implementation. @@ -1937,7 +1937,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for the "maximum" function implementation. */ - std::string maxFunctionString() const; + const std::string &maxFunctionString() const; /** * @brief Set the @c std::string for the "maximum" function implementation. @@ -1958,7 +1958,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for the "secant" function implementation. */ - std::string secFunctionString() const; + const std::string &secFunctionString() const; /** * @brief Set the @c std::string for the "secant" function implementation. @@ -1977,7 +1977,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for the "cosecant" function implementation. */ - std::string cscFunctionString() const; + const std::string &cscFunctionString() const; /** * @brief Set the @c std::string for the "cosecant" function implementation. @@ -1997,7 +1997,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for the "cotangent" function implementation. */ - std::string cotFunctionString() const; + const std::string &cotFunctionString() const; /** * @brief Set the @c std::string for the "cotangent" function @@ -2020,7 +2020,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the "hyperbolic secant" function * implementation. */ - std::string sechFunctionString() const; + const std::string &sechFunctionString() const; /** * @brief Set the @c std::string for the "hyperbolic secant" function @@ -2044,7 +2044,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the "hyperbolic cosecant" function * implementation. */ - std::string cschFunctionString() const; + const std::string &cschFunctionString() const; /** * @brief Set the @c std::string for the "hyperbolic cosecant" function @@ -2068,7 +2068,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the "hyperbolic cotangent" function * implementation. */ - std::string cothFunctionString() const; + const std::string &cothFunctionString() const; /** * @brief Set the @c std::string for the "hyperbolic cotangent" function @@ -2090,7 +2090,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for the "arc secant" function implementation. */ - std::string asecFunctionString() const; + const std::string &asecFunctionString() const; /** * @brief Set the @c std::string for the "arc secant" function @@ -2112,7 +2112,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the "arc cosecant" function * implementation. */ - std::string acscFunctionString() const; + const std::string &acscFunctionString() const; /** * @brief Set the @c std::string for the "arc cosecant" function @@ -2135,7 +2135,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the "arc cotangent" function * implementation. */ - std::string acotFunctionString() const; + const std::string &acotFunctionString() const; /** * @brief Set the @c std::string for the "arc cotangent" function implementation. @@ -2157,7 +2157,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the "arc hyperbolic secant" function * implementation. */ - std::string asechFunctionString() const; + const std::string &asechFunctionString() const; /** * @brief Set the @c std::string for the "arc hyperbolic secant" function @@ -2181,7 +2181,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the "arc hyperbolic cosecant" function * implementation. */ - std::string acschFunctionString() const; + const std::string &acschFunctionString() const; /** * @brief Set the @c std::string for the "arc hyperbolic cosecant" function @@ -2205,7 +2205,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the "arc hyperbolic cotangent" function * implementation. */ - std::string acothFunctionString() const; + const std::string &acothFunctionString() const; /** * @brief Set the @c std::string for the "arc hyperbolic cotangent" function @@ -2228,7 +2228,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for a comment. */ - std::string commentString() const; + const std::string &commentString() const; /** * @brief Set the @c std::string for a comment. @@ -2247,7 +2247,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for an origin comment. */ - std::string originCommentString() const; + const std::string &originCommentString() const; /** * @brief Set the @c std::string for an origin comment. @@ -2271,7 +2271,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for the interface file name. */ - std::string interfaceFileNameString() const; + const std::string &interfaceFileNameString() const; /** * @brief Set the @c std::string for the interface file name. @@ -2290,7 +2290,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for the interface of a header. */ - std::string interfaceHeaderString() const; + const std::string &interfaceHeaderString() const; /** * @brief Set the @c std::string for the interface of a header. @@ -2309,7 +2309,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for an implementation header. */ - std::string implementationHeaderString() const; + const std::string &implementationHeaderString() const; /** * @brief Set the @c std::string for an implementation header. @@ -2332,7 +2332,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for the interface of the version constant. */ - std::string interfaceVersionString() const; + const std::string &interfaceVersionString() const; /** * @brief Set the @c std::string for the interface of the version constant. @@ -2353,7 +2353,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the implementation of the version * constant. */ - std::string implementationVersionString() const; + const std::string &implementationVersionString() const; /** * @brief Set the @c std::string for the implementation of the version @@ -2376,7 +2376,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the interface of the libCellML version * constant. */ - std::string interfaceLibcellmlVersionString() const; + const std::string &interfaceLibcellmlVersionString() const; /** * @brief Set the @c std::string for the interface of the libCellML version @@ -2400,7 +2400,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the implementation of the libCellML * version constant. */ - std::string implementationLibcellmlVersionString() const; + const std::string &implementationLibcellmlVersionString() const; /** * @brief Set the @c std::string for the implementation of the libCellML @@ -2423,7 +2423,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for the interface of the state count constant. */ - std::string interfaceStateCountString() const; + const std::string &interfaceStateCountString() const; /** * @brief Set the @c std::string for the interface of the state count @@ -2446,7 +2446,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the implementation of the state count * constant. */ - std::string implementationStateCountString() const; + const std::string &implementationStateCountString() const; /** * @brief Set the @c std::string for the implementation of the state count @@ -2471,7 +2471,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the interface of the constant count * constant. */ - std::string interfaceConstantCountString() const; + const std::string &interfaceConstantCountString() const; /** * @brief Set the @c std::string for the interface of the constant count @@ -2494,7 +2494,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the implementation of the constant count * constant. */ - std::string implementationConstantCountString() const; + const std::string &implementationConstantCountString() const; /** * @brief Set the @c std::string for the implementation of the constant @@ -2519,7 +2519,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the interface of the computed constant count * constant. */ - std::string interfaceComputedConstantCountString() const; + const std::string &interfaceComputedConstantCountString() const; /** * @brief Set the @c std::string for the interface of the computed constant count @@ -2542,7 +2542,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the implementation of the computed constant count * constant. */ - std::string implementationComputedConstantCountString() const; + const std::string &implementationComputedConstantCountString() const; /** * @brief Set the @c std::string for the implementation of the computed constant @@ -2567,7 +2567,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the interface of the algebraic variable count * constant. */ - std::string interfaceAlgebraicVariableCountString() const; + const std::string &interfaceAlgebraicVariableCountString() const; /** * @brief Set the @c std::string for the interface of the algebraic variable count @@ -2590,7 +2590,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the implementation of the algebraic variable count * constant. */ - std::string implementationAlgebraicVariableCountString() const; + const std::string &implementationAlgebraicVariableCountString() const; /** * @brief Set the @c std::string for the implementation of the algebraic @@ -2615,7 +2615,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the interface of the external variable count * constant. */ - std::string interfaceExternalVariableCountString() const; + const std::string &interfaceExternalVariableCountString() const; /** * @brief Set the @c std::string for the interface of the external variable count @@ -2638,7 +2638,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the implementation of the external variable count * constant. */ - std::string implementationExternalVariableCountString() const; + const std::string &implementationExternalVariableCountString() const; /** * @brief Set the @c std::string for the implementation of the external @@ -2663,7 +2663,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the data structure for the variable * information object. */ - std::string variableInfoObjectString() const; + const std::string &variableInfoObjectString() const; /** * @brief Set the @c std::string for the data structure for the variable @@ -2690,7 +2690,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the interface of some information about * the variable of integration. */ - std::string interfaceVoiInfoString() const; + const std::string &interfaceVoiInfoString() const; /** * @brief Set the @c std::string for the interface of some information about @@ -2714,7 +2714,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the implementation of some information * about the variable of integration. */ - std::string implementationVoiInfoString() const; + const std::string &implementationVoiInfoString() const; /** * @brief Set the @c std::string for the implementation of some information @@ -2740,7 +2740,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the interface of some information about * the different states. */ - std::string interfaceStateInfoString() const; + const std::string &interfaceStateInfoString() const; /** * @brief Set the @c std::string for the interface of some information about @@ -2764,7 +2764,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the implementation of some information * about the different states. */ - std::string implementationStateInfoString() const; + const std::string &implementationStateInfoString() const; /** * @brief Set the @c std::string for the implementation of some information @@ -2790,7 +2790,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the interface of some information about * the different constants. */ - std::string interfaceConstantInfoString() const; + const std::string &interfaceConstantInfoString() const; /** * @brief Set the @c std::string for the interface of some information about @@ -2814,7 +2814,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the implementation of some information * about the different constants. */ - std::string implementationConstantInfoString() const; + const std::string &implementationConstantInfoString() const; /** * @brief Set the @c std::string for the implementation of some information @@ -2840,7 +2840,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the interface of some information about * the different computed constants. */ - std::string interfaceComputedConstantInfoString() const; + const std::string &interfaceComputedConstantInfoString() const; /** * @brief Set the @c std::string for the interface of some information about @@ -2864,7 +2864,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the implementation of some information * about the different computed constants. */ - std::string implementationComputedConstantInfoString() const; + const std::string &implementationComputedConstantInfoString() const; /** * @brief Set the @c std::string for the implementation of some information @@ -2890,7 +2890,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the interface of some information about * the different algebraic variables. */ - std::string interfaceAlgebraicVariableInfoString() const; + const std::string &interfaceAlgebraicVariableInfoString() const; /** * @brief Set the @c std::string for the interface of some information about @@ -2914,7 +2914,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the implementation of some information * about the different algebraic variables. */ - std::string implementationAlgebraicVariableInfoString() const; + const std::string &implementationAlgebraicVariableInfoString() const; /** * @brief Set the @c std::string for the implementation of some information @@ -2940,7 +2940,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the interface of some information about * the different external variables. */ - std::string interfaceExternalVariableInfoString() const; + const std::string &interfaceExternalVariableInfoString() const; /** * @brief Set the @c std::string for the interface of some information about @@ -2964,7 +2964,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the implementation of some information * about the different external variables. */ - std::string implementationExternalVariableInfoString() const; + const std::string &implementationExternalVariableInfoString() const; /** * @brief Set the @c std::string for the implementation of some information @@ -2990,7 +2990,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for an entry in an array for some information * about a variable. */ - std::string variableInfoEntryString() const; + const std::string &variableInfoEntryString() const; /** * @brief Set the @c std::string for an entry in an array for some @@ -3014,7 +3014,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for the name of the variable of integration. */ - std::string voiString() const; + const std::string &voiString() const; /** * @brief Set the @c std::string for the name of the variable of @@ -3034,7 +3034,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for the name of the states array. */ - std::string statesArrayString() const; + const std::string &statesArrayString() const; /** * @brief Set the @c std::string for the name of the states array. @@ -3053,7 +3053,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for the name of the rates array. */ - std::string ratesArrayString() const; + const std::string &ratesArrayString() const; /** * @brief Set the @c std::string for the name of the rates array. @@ -3072,7 +3072,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for the name of the constants array. */ - std::string constantsArrayString() const; + const std::string &constantsArrayString() const; /** * @brief Set the @c std::string for the name of the constants array. @@ -3091,7 +3091,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for the name of the computed constants array. */ - std::string computedConstantsArrayString() const; + const std::string &computedConstantsArrayString() const; /** * @brief Set the @c std::string for the name of the computed constants array. @@ -3110,7 +3110,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for the name of the algebraic variables array. */ - std::string algebraicVariablesArrayString() const; + const std::string &algebraicVariablesArrayString() const; /** * @brief Set the @c std::string for the name of the algebraic variables array. @@ -3129,7 +3129,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for the name of the external variables array. */ - std::string externalVariablesArrayString() const; + const std::string &externalVariablesArrayString() const; /** * @brief Set the @c std::string for the name of the external variables array. @@ -3155,7 +3155,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the type definition of an external * variable method. */ - std::string externalVariableMethodTypeDefinitionString(bool forDifferentialModel) const; + const std::string &externalVariableMethodTypeDefinitionString(bool forDifferentialModel) const; /** * @brief Set the @c std::string for the type definition of an external @@ -3184,7 +3184,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for the call to the external variable method. */ - std::string externalVariableMethodCallString(bool forDifferentialModel) const; + const std::string &externalVariableMethodCallString(bool forDifferentialModel) const; /** * @brief Set the @c std::string for the call to the external variable @@ -3218,8 +3218,8 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the data structure for the root finding * information object. */ - std::string rootFindingInfoObjectString(bool forDifferentialModel, - bool withExternalVariables) const; + const std::string &rootFindingInfoObjectString(bool forDifferentialModel, + bool withExternalVariables) const; /** * @brief Set the @c std::string for the data structure for the root finding @@ -3247,7 +3247,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for the external NLA solve method. */ - std::string externNlaSolveMethodString() const; + const std::string &externNlaSolveMethodString() const; /** * @brief Set the @c std::string for the external NLA solve method. @@ -3271,8 +3271,8 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for the call to the find root method. */ - std::string findRootCallString(bool forDifferentialModel, - bool withExternalVariables) const; + const std::string &findRootCallString(bool forDifferentialModel, + bool withExternalVariables) const; /** * @brief Set the @c std::string for the call to the find root method. @@ -3304,8 +3304,8 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for the find root method. */ - std::string findRootMethodString(bool forDifferentialModel, - bool withExternalVariables) const; + const std::string &findRootMethodString(bool forDifferentialModel, + bool withExternalVariables) const; /** * @brief Set the @c std::string for the find root method. @@ -3341,8 +3341,8 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for the call to the NLA solve method. */ - std::string nlaSolveCallString(bool forDifferentialModel, - bool withExternalVariables) const; + const std::string &nlaSolveCallString(bool forDifferentialModel, + bool withExternalVariables) const; /** * @brief Set the @c std::string for the call to the NLA solve method. @@ -3377,8 +3377,8 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for the objective function method. */ - std::string objectiveFunctionMethodString(bool forDifferentialModel, - bool withExternalVariables) const; + const std::string &objectiveFunctionMethodString(bool forDifferentialModel, + bool withExternalVariables) const; /** * @brief Set the @c std::string for the objective function method. @@ -3410,7 +3410,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the @c u array used in the objective function * and find root methods. */ - std::string uArrayString() const; + const std::string &uArrayString() const; /** * @brief Set the @c std::string for the @c u array used in the objective @@ -3436,7 +3436,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the @f array used in the objective function * and find root methods. */ - std::string fArrayString() const; + const std::string &fArrayString() const; /** * @brief Set the @c std::string for the @f array used in the objective @@ -3459,7 +3459,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for the interface to create the states array. */ - std::string interfaceCreateStatesArrayMethodString() const; + const std::string &interfaceCreateStatesArrayMethodString() const; /** * @brief Set the @c std::string for the interface to create the states @@ -3482,7 +3482,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the implementation to create the states * array. */ - std::string implementationCreateStatesArrayMethodString() const; + const std::string &implementationCreateStatesArrayMethodString() const; /** * @brief Set the @c std::string for the implementation to create the states @@ -3503,7 +3503,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for the interface to create the constants array. */ - std::string interfaceCreateConstantsArrayMethodString() const; + const std::string &interfaceCreateConstantsArrayMethodString() const; /** * @brief Set the @c std::string for the interface to create the constants @@ -3526,7 +3526,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the implementation to create the constants * array. */ - std::string implementationCreateConstantsArrayMethodString() const; + const std::string &implementationCreateConstantsArrayMethodString() const; /** * @brief Set the @c std::string for the implementation to create the constants @@ -3547,7 +3547,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for the interface to create the computed constants array. */ - std::string interfaceCreateComputedConstantsArrayMethodString() const; + const std::string &interfaceCreateComputedConstantsArrayMethodString() const; /** * @brief Set the @c std::string for the interface to create the computed constants @@ -3570,7 +3570,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the implementation to create the computed constants * array. */ - std::string implementationCreateComputedConstantsArrayMethodString() const; + const std::string &implementationCreateComputedConstantsArrayMethodString() const; /** * @brief Set the @c std::string for the implementation to create the computed constants @@ -3591,7 +3591,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for the interface to create the algebraic variables array. */ - std::string interfaceCreateAlgebraicVariablesArrayMethodString() const; + const std::string &interfaceCreateAlgebraicVariablesArrayMethodString() const; /** * @brief Set the @c std::string for the interface to create the algebraic variables @@ -3614,7 +3614,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the implementation to create the algebraic variables * array. */ - std::string implementationCreateAlgebraicVariablesArrayMethodString() const; + const std::string &implementationCreateAlgebraicVariablesArrayMethodString() const; /** * @brief Set the @c std::string for the implementation to create the algebraic variables @@ -3635,7 +3635,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for the interface to create the external variables array. */ - std::string interfaceCreateExternalVariablesArrayMethodString() const; + const std::string &interfaceCreateExternalVariablesArrayMethodString() const; /** * @brief Set the @c std::string for the interface to create the external variables @@ -3658,7 +3658,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the implementation to create the external variables * array. */ - std::string implementationCreateExternalVariablesArrayMethodString() const; + const std::string &implementationCreateExternalVariablesArrayMethodString() const; /** * @brief Set the @c std::string for the implementation to create the external variables @@ -3678,7 +3678,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for the interface to delete an array. */ - std::string interfaceDeleteArrayMethodString() const; + const std::string &interfaceDeleteArrayMethodString() const; /** * @brief Set the @c std::string for the interface to delete an array. @@ -3697,7 +3697,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for the implementation to delete an array. */ - std::string implementationDeleteArrayMethodString() const; + const std::string &implementationDeleteArrayMethodString() const; /** * @brief Set the @c std::string for the implementation to delete an array. @@ -3719,7 +3719,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for the interface to initialise variables. */ - std::string interfaceInitialiseArraysMethodString(bool forDifferentialModel) const; + const std::string &interfaceInitialiseArraysMethodString(bool forDifferentialModel) const; /** * @brief Set the @c std::string for the interface to initialise variables. @@ -3746,7 +3746,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the implementation to initialise * variables. */ - std::string implementationInitialiseArraysMethodString(bool forDifferentialModel) const; + const std::string &implementationInitialiseArraysMethodString(bool forDifferentialModel) const; /** * @brief Set the @c std::string for the implementation to initialise @@ -3777,7 +3777,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the interface to compute computed * constants. */ - std::string interfaceComputeComputedConstantsMethodString(bool forDifferentialModel) const; + const std::string &interfaceComputeComputedConstantsMethodString(bool forDifferentialModel) const; /** * @brief Set the @c std::string for the interface to compute computed @@ -3806,7 +3806,7 @@ class LIBCELLML_EXPORT GeneratorProfile * @return The @c std::string for the implementation to compute computed * constants. */ - std::string implementationComputeComputedConstantsMethodString(bool forDifferentialModel) const; + const std::string &implementationComputeComputedConstantsMethodString(bool forDifferentialModel) const; /** * @brief Set the @c std::string for the implementation to compute computed @@ -3835,7 +3835,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for the interface to compute rates. */ - std::string interfaceComputeRatesMethodString(bool withExternalVariables) const; + const std::string &interfaceComputeRatesMethodString(bool withExternalVariables) const; /** * @brief Set the @c std::string for the interface to compute rates. @@ -3860,7 +3860,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for the implementation to compute rates. */ - std::string implementationComputeRatesMethodString(bool withExternalVariables) const; + const std::string &implementationComputeRatesMethodString(bool withExternalVariables) const; /** * @brief Set the @c std::string for the implementation to compute rates. @@ -3889,8 +3889,8 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for the interface to compute variables. */ - std::string interfaceComputeVariablesMethodString(bool forDifferentialModel, - bool withExternalVariables) const; + const std::string &interfaceComputeVariablesMethodString(bool forDifferentialModel, + bool withExternalVariables) const; /** * @brief Set the @c std::string for the interface to compute variables. @@ -3921,8 +3921,8 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for the implementation to compute variables. */ - std::string implementationComputeVariablesMethodString(bool forDifferentialModel, - bool withExternalVariables) const; + const std::string &implementationComputeVariablesMethodString(bool forDifferentialModel, + bool withExternalVariables) const; /** * @brief Set the @c std::string for the implementation to compute @@ -3950,7 +3950,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for an empty method. */ - std::string emptyMethodString() const; + const std::string &emptyMethodString() const; /** * @brief Set the @c std::string for an empty method. @@ -3968,7 +3968,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for an indent. */ - std::string indentString() const; + const std::string &indentString() const; /** * @brief Set the @c std::string for an indent. @@ -3986,7 +3986,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for declaring a variable. */ - std::string variableDeclarationString() const; + const std::string &variableDeclarationString() const; /** * @brief Set the @c std::string for declaring a variable. @@ -4005,7 +4005,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for opening an array. */ - std::string openArrayString() const; + const std::string &openArrayString() const; /** * @brief Set the @c std::string for opening an array. @@ -4023,7 +4023,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for closing an array. */ - std::string closeArrayString() const; + const std::string &closeArrayString() const; /** * @brief Set the @c std::string for closing an array. @@ -4041,7 +4041,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for separating elements in an array. */ - std::string arrayElementSeparatorString() const; + const std::string &arrayElementSeparatorString() const; /** * @brief Set the @c std::string for separating elements in an array. @@ -4060,7 +4060,7 @@ class LIBCELLML_EXPORT GeneratorProfile * * @return The @c std::string for a command separator. */ - std::string commandSeparatorString() const; + const std::string &commandSeparatorString() const; /** * @brief Set the @c std::string for a command separator. diff --git a/src/api/libcellml/importedentity.h b/src/api/libcellml/importedentity.h index caecef13a..7ca3cb1b2 100644 --- a/src/api/libcellml/importedentity.h +++ b/src/api/libcellml/importedentity.h @@ -79,7 +79,7 @@ class LIBCELLML_EXPORT ImportedEntity * @return The reference to the entity in the imported model, the empty * string if it is not set. */ - std::string importReference() const; + const std::string &importReference() const; /** * @brief Set the import reference. diff --git a/src/api/libcellml/importsource.h b/src/api/libcellml/importsource.h index 16fdb9f84..180cb88a8 100644 --- a/src/api/libcellml/importsource.h +++ b/src/api/libcellml/importsource.h @@ -65,7 +65,7 @@ class LIBCELLML_EXPORT ImportSource: public Entity * * @return The URL of the source @ref Model if set otherwise the empty string. */ - std::string url() const; + const std::string &url() const; /** * @brief Set the source @ref Model's URL. diff --git a/src/api/libcellml/issue.h b/src/api/libcellml/issue.h index 51d5bf41f..033c9ab14 100644 --- a/src/api/libcellml/issue.h +++ b/src/api/libcellml/issue.h @@ -238,7 +238,7 @@ class LIBCELLML_EXPORT Issue * * @return The @c std::string description of the issue. */ - std::string description() const; + const std::string &description() const; /** * @brief Get the level of this issue. diff --git a/src/api/libcellml/namedentity.h b/src/api/libcellml/namedentity.h index 21ab58c89..c1f5cdbb8 100644 --- a/src/api/libcellml/namedentity.h +++ b/src/api/libcellml/namedentity.h @@ -54,7 +54,7 @@ class LIBCELLML_EXPORT NamedEntity: public ParentedEntity * * @return @c std::string representation of the Entity name. */ - std::string name() const; + const std::string &name() const; /** * @brief Remove the name of the Entity. diff --git a/src/api/libcellml/reset.h b/src/api/libcellml/reset.h index 04d2a8703..14cdd4c6f 100644 --- a/src/api/libcellml/reset.h +++ b/src/api/libcellml/reset.h @@ -147,7 +147,7 @@ class LIBCELLML_EXPORT Reset: public ParentedEntity * * @return @c std::string test value for this reset. */ - std::string testValue() const; + const std::string &testValue() const; /** * @brief Set the test value string for this reset. @@ -194,7 +194,7 @@ class LIBCELLML_EXPORT Reset: public ParentedEntity * * @return @c std::string The identifier of the test value for this reset. */ - std::string testValueId() const; + const std::string &testValueId() const; /** * @brief Append the argument to the reset value for this reset. @@ -213,7 +213,7 @@ class LIBCELLML_EXPORT Reset: public ParentedEntity * * @return @c std::string reset value for this reset. */ - std::string resetValue() const; + const std::string &resetValue() const; /** * @brief Set the reset value math for this reset. @@ -259,7 +259,7 @@ class LIBCELLML_EXPORT Reset: public ParentedEntity * * @return @c std::string The identifier of the reset value for this reset. */ - std::string resetValueId() const; + const std::string &resetValueId() const; /** * @brief Create a clone of this reset. diff --git a/src/api/libcellml/variable.h b/src/api/libcellml/variable.h index 2d9e6292d..82b9525c4 100644 --- a/src/api/libcellml/variable.h +++ b/src/api/libcellml/variable.h @@ -368,7 +368,7 @@ class LIBCELLML_EXPORT Variable: public NamedEntity * * @return the initial value as a @c std::string. */ - std::string initialValue() const; + const std::string &initialValue() const; /** * @brief Clear the initial value for this variable. @@ -411,7 +411,7 @@ class LIBCELLML_EXPORT Variable: public NamedEntity * * @return the interface type as a @c std::string. */ - std::string interfaceType() const; + const std::string &interfaceType() const; /** * @brief Clear the interface type for this variable. diff --git a/src/commonutils.cpp b/src/commonutils.cpp index 412691ff7..b539f9958 100644 --- a/src/commonutils.cpp +++ b/src/commonutils.cpp @@ -25,14 +25,16 @@ namespace libcellml { libcellml::ModelPtr owningModel(const libcellml::ParentedEntityConstPtr &entity) { - auto model = std::dynamic_pointer_cast(entity->parent()); - auto component = owningComponent(entity); - while ((model == nullptr) && (component != nullptr)) { - model = std::dynamic_pointer_cast(component->parent()); - component = owningComponent(component); + auto parent = entity->parent(); + while (parent != nullptr) { + auto model = std::dynamic_pointer_cast(parent); + if (model != nullptr) { + return model; + } + parent = parent->parent(); } - return model; + return nullptr; } libcellml::ComponentPtr owningComponent(const libcellml::ParentedEntityConstPtr &entity) diff --git a/src/component.cpp b/src/component.cpp index c2c7fe146..26d7da068 100644 --- a/src/component.cpp +++ b/src/component.cpp @@ -37,19 +37,19 @@ namespace libcellml { std::vector::const_iterator Component::ComponentImpl::findVariable(const std::string &name) const { return std::find_if(mVariables.begin(), mVariables.end(), - [=](const VariablePtr &v) -> bool { return v->name() == name; }); + [&](const VariablePtr &v) -> bool { return v->name() == name; }); } std::vector::const_iterator Component::ComponentImpl::findVariable(const VariablePtr &variable) const { return std::find_if(mVariables.begin(), mVariables.end(), - [=](const VariablePtr &v) -> bool { return v->equals(variable); }); + [&](const VariablePtr &v) -> bool { return v->equals(variable); }); } std::vector::const_iterator Component::ComponentImpl::findReset(const ResetPtr &reset) const { return std::find_if(mResets.begin(), mResets.end(), - [=](const ResetPtr &r) -> bool { return r->equals(reset); }); + [&](const ResetPtr &r) -> bool { return r->equals(reset); }); } bool Component::ComponentImpl::equalVariables(const ComponentPtr &other) const @@ -188,7 +188,7 @@ void Component::appendMath(const std::string &math) pFunc()->mMath.append(math); } -std::string Component::math() const +const std::string &Component::math() const { return pFunc()->mMath; } diff --git a/src/componententity.cpp b/src/componententity.cpp index de8e28184..32500d400 100644 --- a/src/componententity.cpp +++ b/src/componententity.cpp @@ -29,13 +29,13 @@ namespace libcellml { std::vector::const_iterator ComponentEntity::ComponentEntityImpl::findComponent(const std::string &name) const { return std::find_if(mComponents.begin(), mComponents.end(), - [=](const ComponentPtr &c) -> bool { return c->name() == name; }); + [&](const ComponentPtr &c) -> bool { return c->name() == name; }); } std::vector::const_iterator ComponentEntity::ComponentEntityImpl::findComponent(const ComponentPtr &component) const { return std::find_if(mComponents.begin(), mComponents.end(), - [=](const ComponentPtr &c) -> bool { return c->equals(component); }); + [&](const ComponentPtr &c) -> bool { return c->equals(component); }); } ComponentEntity::ComponentEntityImpl *ComponentEntity::pFunc() @@ -260,7 +260,7 @@ void ComponentEntity::setEncapsulationId(const std::string &id) pFunc()->mEncapsulationId = id; } -std::string ComponentEntity::encapsulationId() const +const std::string &ComponentEntity::encapsulationId() const { return pFunc()->mEncapsulationId; } diff --git a/src/debug.cpp b/src/debug.cpp index d3aea479b..49d10d2f5 100644 --- a/src/debug.cpp +++ b/src/debug.cpp @@ -648,6 +648,7 @@ std::string doPrintAstAsTree(const AnalyserEquationAstPtr &ast, } std::string res; + res.reserve(512); std::string prevStr = SPACES; AnalyserEquationAstTrunk trunk(prevTrunk, prevStr); auto astLeftChild = ast->leftChild(); diff --git a/src/entity.cpp b/src/entity.cpp index abd65dd9f..9226b807c 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -34,7 +34,7 @@ void Entity::setId(const std::string &id) pFunc()->mId = id; } -std::string Entity::id() const +const std::string &Entity::id() const { return pFunc()->mId; } diff --git a/src/generator.cpp b/src/generator.cpp index be3bd6096..228d82093 100644 --- a/src/generator.cpp +++ b/src/generator.cpp @@ -16,7 +16,9 @@ limitations under the License. #include "libcellml/generator.h" -#include +#include +#include +#include #include "libcellml/analyserequation.h" #include "libcellml/analyserequationast.h" @@ -40,6 +42,8 @@ namespace libcellml { void Generator::GeneratorImpl::reset() { mCode = {}; + + mCode.reserve(32768); } std::string Generator::GeneratorImpl::analyserVariableIndexString(const AnalyserVariablePtr &analyserVariable) @@ -47,7 +51,7 @@ std::string Generator::GeneratorImpl::analyserVariableIndexString(const Analyser // Determine the actual index of the analyser variable in the list of analyser variables by accounting for the fact // that some analyser variables may be untracked. - auto analyserVariables = libcellml::analyserVariables(analyserVariable); + const auto &analyserVariables = libcellml::analyserVariables(analyserVariable); if (analyserVariables.empty()) { return convertToString(analyserVariable->index()); @@ -57,7 +61,7 @@ std::string Generator::GeneratorImpl::analyserVariableIndexString(const Analyser size_t res = MAX_SIZE_T; for (;;) { - auto analyserVar = analyserVariables[++i]; + const auto &analyserVar = analyserVariables[++i]; if (isTrackedVariable(analyserVar, true)) { ++res; @@ -249,9 +253,13 @@ bool Generator::GeneratorImpl::modifiedProfile() const sha1(profileContents) != PYTHON_GENERATOR_PROFILE_SHA1; } -std::string Generator::GeneratorImpl::newLineIfNeeded() +void Generator::GeneratorImpl::addCode(const std::string &code) { - return mCode.empty() ? "" : "\n"; + if (!mCode.empty()) { + mCode += '\n'; + } + + mCode += code; } void Generator::GeneratorImpl::addOriginCommentCode() @@ -267,17 +275,15 @@ void Generator::GeneratorImpl::addOriginCommentCode() "Python"; profileInformation += " profile of"; - mCode += newLineIfNeeded() - + replace(mProfile->commentString(), - "[CODE]", replace(replace(mProfile->originCommentString(), "[PROFILE_INFORMATION]", profileInformation), "[LIBCELLML_VERSION]", versionString())); + addCode(replace(mProfile->commentString(), + "[CODE]", replace(replace(mProfile->originCommentString(), "[PROFILE_INFORMATION]", profileInformation), "[LIBCELLML_VERSION]", versionString()))); } } void Generator::GeneratorImpl::addInterfaceHeaderCode() { if (!mProfile->interfaceHeaderString().empty()) { - mCode += newLineIfNeeded() - + mProfile->interfaceHeaderString(); + addCode(mProfile->interfaceHeaderString()); } } @@ -290,9 +296,8 @@ void Generator::GeneratorImpl::addImplementationHeaderCode() if (!mProfile->implementationHeaderString().empty() && ((hasInterfaceFileName && !mProfile->interfaceFileNameString().empty()) || !hasInterfaceFileName)) { - mCode += newLineIfNeeded() - + replace(mProfile->implementationHeaderString(), - "[INTERFACE_FILE_NAME]", mProfile->interfaceFileNameString()); + addCode(replace(mProfile->implementationHeaderString(), + "[INTERFACE_FILE_NAME]", mProfile->interfaceFileNameString())); } } @@ -306,9 +311,47 @@ void Generator::GeneratorImpl::addVersionAndLibcellmlVersionCode(bool interface) code += mProfile->interfaceVersionString(); } else { if (modifiedProfile()) { - static const std::regex regEx("([0-9]+\\.[0-9]+\\.[0-9]+)"); + // Find the semver pattern (X.Y.Z) and append ".post0". + + auto versionString = mProfile->implementationVersionString(); + size_t start = std::string::npos; + + for (size_t i = 0; i < versionString.size(); ++i) { + if (std::isdigit(static_cast(versionString[i]))) { + if (start == std::string::npos) { + start = i; + } + } else if (versionString[i] == '.' && start != std::string::npos) { + // Continue (it's part of the version string). + } else { + if (start != std::string::npos) { + auto candidate = versionString.substr(start, i - start); + + // Check that it has exactly 2 dots (semver X.Y.Z). + + if (std::count(candidate.begin(), candidate.end(), '.') == 2) { + versionString.insert(i, ".post0"); + + break; + } + } + + start = std::string::npos; + } + } + + // If we reached the end of the string and we found a semver pattern, then append ".post0" to the end of + // the string. + + if (start != std::string::npos) { + auto candidate = versionString.substr(start); + + if (std::count(candidate.begin(), candidate.end(), '.') == 2) { + versionString += ".post0"; + } + } - code += std::regex_replace(mProfile->implementationVersionString(), regEx, "$1.post0"); + code += versionString; } else { code += mProfile->implementationVersionString(); } @@ -324,8 +367,7 @@ void Generator::GeneratorImpl::addVersionAndLibcellmlVersionCode(bool interface) } if (!code.empty()) { - mCode += newLineIfNeeded() - + code; + addCode(code); } } @@ -339,7 +381,7 @@ void Generator::GeneratorImpl::addStateAndVariableCountCode(bool interface) code += interface ? mProfile->interfaceStateCountString() : replace(mProfile->implementationStateCountString(), - "[STATE_COUNT]", std::to_string(mAnalyserModel->stateCount())); + "[STATE_COUNT]", std::format("{}", mAnalyserModel->stateCount())); } if ((interface && !mProfile->interfaceConstantCountString().empty()) @@ -347,7 +389,7 @@ void Generator::GeneratorImpl::addStateAndVariableCountCode(bool interface) code += interface ? mProfile->interfaceConstantCountString() : replace(mProfile->implementationConstantCountString(), - "[CONSTANT_COUNT]", std::to_string((mVariableTracker != nullptr) ? mVariableTracker->trackedConstantCount(mAnalyserModel) : mAnalyserModel->constantCount())); + "[CONSTANT_COUNT]", std::format("{}", (mVariableTracker != nullptr) ? mVariableTracker->trackedConstantCount(mAnalyserModel) : mAnalyserModel->constantCount())); } if ((interface && !mProfile->interfaceComputedConstantCountString().empty()) @@ -355,7 +397,7 @@ void Generator::GeneratorImpl::addStateAndVariableCountCode(bool interface) code += interface ? mProfile->interfaceComputedConstantCountString() : replace(mProfile->implementationComputedConstantCountString(), - "[COMPUTED_CONSTANT_COUNT]", std::to_string((mVariableTracker != nullptr) ? mVariableTracker->trackedComputedConstantCount(mAnalyserModel) : mAnalyserModel->computedConstantCount())); + "[COMPUTED_CONSTANT_COUNT]", std::format("{}", (mVariableTracker != nullptr) ? mVariableTracker->trackedComputedConstantCount(mAnalyserModel) : mAnalyserModel->computedConstantCount())); } if ((interface && !mProfile->interfaceAlgebraicVariableCountString().empty()) @@ -363,7 +405,7 @@ void Generator::GeneratorImpl::addStateAndVariableCountCode(bool interface) code += interface ? mProfile->interfaceAlgebraicVariableCountString() : replace(mProfile->implementationAlgebraicVariableCountString(), - "[ALGEBRAIC_VARIABLE_COUNT]", std::to_string((mVariableTracker != nullptr) ? mVariableTracker->trackedAlgebraicVariableCount(mAnalyserModel) : mAnalyserModel->algebraicVariableCount())); + "[ALGEBRAIC_VARIABLE_COUNT]", std::format("{}", (mVariableTracker != nullptr) ? mVariableTracker->trackedAlgebraicVariableCount(mAnalyserModel) : mAnalyserModel->algebraicVariableCount())); } if ((mAnalyserModel->externalVariableCount() != 0) @@ -372,12 +414,11 @@ void Generator::GeneratorImpl::addStateAndVariableCountCode(bool interface) code += interface ? mProfile->interfaceExternalVariableCountString() : replace(mProfile->implementationExternalVariableCountString(), - "[EXTERNAL_VARIABLE_COUNT]", std::to_string(mAnalyserModel->externalVariableCount())); + "[EXTERNAL_VARIABLE_COUNT]", std::format("{}", mAnalyserModel->externalVariableCount())); } if (!code.empty()) { - mCode += newLineIfNeeded() - + code; + addCode(code); } } @@ -394,16 +435,15 @@ std::string Generator::GeneratorImpl::generateVariableInfoObjectCode(const std:: } return replace(replace(replace(objectString, - "[COMPONENT_SIZE]", std::to_string(componentSize)), - "[NAME_SIZE]", std::to_string(nameSize)), - "[UNITS_SIZE]", std::to_string(unitsSize)); + "[COMPONENT_SIZE]", std::format("{}", componentSize)), + "[NAME_SIZE]", std::format("{}", nameSize)), + "[UNITS_SIZE]", std::format("{}", unitsSize)); } void Generator::GeneratorImpl::addVariableInfoObjectCode() { if (!mProfile->variableInfoObjectString().empty()) { - mCode += newLineIfNeeded() - + generateVariableInfoObjectCode(mProfile->variableInfoObjectString()); + addCode(generateVariableInfoObjectCode(mProfile->variableInfoObjectString())); } } @@ -449,8 +489,7 @@ void Generator::GeneratorImpl::addInterfaceVariableInfoCode() } if (!code.empty()) { - mCode += newLineIfNeeded() - + code; + addCode(code); } } @@ -463,6 +502,8 @@ void Generator::GeneratorImpl::addImplementationVariableInfoCode(const std::stri && !mProfile->arrayElementSeparatorString().empty()) { std::string infoElementsCode; + infoElementsCode.reserve(analyserVariables.size() * 200); + for (const auto &analyserVariable : analyserVariables) { if (isTrackedVariable(analyserVariable, true)) { if (!infoElementsCode.empty()) { @@ -482,8 +523,7 @@ void Generator::GeneratorImpl::addImplementationVariableInfoCode(const std::stri infoElementsCode += "\n"; } - mCode += newLineIfNeeded() - + replace(variableInfoString, "[CODE]", infoElementsCode); + addCode(replace(variableInfoString, "[CODE]", infoElementsCode)); } } @@ -507,74 +547,62 @@ void Generator::GeneratorImpl::addArithmeticFunctionsCode() { if (mAnalyserModel->needEqFunction() && !mProfile->hasEqOperator() && !mProfile->eqFunctionString().empty()) { - mCode += newLineIfNeeded() - + mProfile->eqFunctionString(); + addCode(mProfile->eqFunctionString()); } if (mAnalyserModel->needNeqFunction() && !mProfile->hasNeqOperator() && !mProfile->neqFunctionString().empty()) { - mCode += newLineIfNeeded() - + mProfile->neqFunctionString(); + addCode(mProfile->neqFunctionString()); } if (mAnalyserModel->needLtFunction() && !mProfile->hasLtOperator() && !mProfile->ltFunctionString().empty()) { - mCode += newLineIfNeeded() - + mProfile->ltFunctionString(); + addCode(mProfile->ltFunctionString()); } if (mAnalyserModel->needLeqFunction() && !mProfile->hasLeqOperator() && !mProfile->leqFunctionString().empty()) { - mCode += newLineIfNeeded() - + mProfile->leqFunctionString(); + addCode(mProfile->leqFunctionString()); } if (mAnalyserModel->needGtFunction() && !mProfile->hasGtOperator() && !mProfile->gtFunctionString().empty()) { - mCode += newLineIfNeeded() - + mProfile->gtFunctionString(); + addCode(mProfile->gtFunctionString()); } if (mAnalyserModel->needGeqFunction() && !mProfile->hasGeqOperator() && !mProfile->geqFunctionString().empty()) { - mCode += newLineIfNeeded() - + mProfile->geqFunctionString(); + addCode(mProfile->geqFunctionString()); } if (mAnalyserModel->needAndFunction() && !mProfile->hasAndOperator() && !mProfile->andFunctionString().empty()) { - mCode += newLineIfNeeded() - + mProfile->andFunctionString(); + addCode(mProfile->andFunctionString()); } if (mAnalyserModel->needOrFunction() && !mProfile->hasOrOperator() && !mProfile->orFunctionString().empty()) { - mCode += newLineIfNeeded() - + mProfile->orFunctionString(); + addCode(mProfile->orFunctionString()); } if (mAnalyserModel->needXorFunction() && !mProfile->hasXorOperator() && !mProfile->xorFunctionString().empty()) { - mCode += newLineIfNeeded() - + mProfile->xorFunctionString(); + addCode(mProfile->xorFunctionString()); } if (mAnalyserModel->needNotFunction() && !mProfile->hasNotOperator() && !mProfile->notFunctionString().empty()) { - mCode += newLineIfNeeded() - + mProfile->notFunctionString(); + addCode(mProfile->notFunctionString()); } if (mAnalyserModel->needMinFunction() && !mProfile->minFunctionString().empty()) { - mCode += newLineIfNeeded() - + mProfile->minFunctionString(); + addCode(mProfile->minFunctionString()); } if (mAnalyserModel->needMaxFunction() && !mProfile->maxFunctionString().empty()) { - mCode += newLineIfNeeded() - + mProfile->maxFunctionString(); + addCode(mProfile->maxFunctionString()); } } @@ -582,74 +610,62 @@ void Generator::GeneratorImpl::addTrigonometricFunctionsCode() { if (mAnalyserModel->needSecFunction() && !mProfile->secFunctionString().empty()) { - mCode += newLineIfNeeded() - + mProfile->secFunctionString(); + addCode(mProfile->secFunctionString()); } if (mAnalyserModel->needCscFunction() && !mProfile->cscFunctionString().empty()) { - mCode += newLineIfNeeded() - + mProfile->cscFunctionString(); + addCode(mProfile->cscFunctionString()); } if (mAnalyserModel->needCotFunction() && !mProfile->cotFunctionString().empty()) { - mCode += newLineIfNeeded() - + mProfile->cotFunctionString(); + addCode(mProfile->cotFunctionString()); } if (mAnalyserModel->needSechFunction() && !mProfile->sechFunctionString().empty()) { - mCode += newLineIfNeeded() - + mProfile->sechFunctionString(); + addCode(mProfile->sechFunctionString()); } if (mAnalyserModel->needCschFunction() && !mProfile->cschFunctionString().empty()) { - mCode += newLineIfNeeded() - + mProfile->cschFunctionString(); + addCode(mProfile->cschFunctionString()); } if (mAnalyserModel->needCothFunction() && !mProfile->cothFunctionString().empty()) { - mCode += newLineIfNeeded() - + mProfile->cothFunctionString(); + addCode(mProfile->cothFunctionString()); } if (mAnalyserModel->needAsecFunction() && !mProfile->asecFunctionString().empty()) { - mCode += newLineIfNeeded() - + mProfile->asecFunctionString(); + addCode(mProfile->asecFunctionString()); } if (mAnalyserModel->needAcscFunction() && !mProfile->acscFunctionString().empty()) { - mCode += newLineIfNeeded() - + mProfile->acscFunctionString(); + addCode(mProfile->acscFunctionString()); } if (mAnalyserModel->needAcotFunction() && !mProfile->acotFunctionString().empty()) { - mCode += newLineIfNeeded() - + mProfile->acotFunctionString(); + addCode(mProfile->acotFunctionString()); } if (mAnalyserModel->needAsechFunction() && !mProfile->asechFunctionString().empty()) { - mCode += newLineIfNeeded() - + mProfile->asechFunctionString(); + addCode(mProfile->asechFunctionString()); } if (mAnalyserModel->needAcschFunction() && !mProfile->acschFunctionString().empty()) { - mCode += newLineIfNeeded() - + mProfile->acschFunctionString(); + addCode(mProfile->acschFunctionString()); } if (mAnalyserModel->needAcothFunction() && !mProfile->acothFunctionString().empty()) { - mCode += newLineIfNeeded() - + mProfile->acothFunctionString(); + addCode(mProfile->acothFunctionString()); } } @@ -685,8 +701,7 @@ void Generator::GeneratorImpl::addInterfaceCreateDeleteArrayMethodsCode() } if (!code.empty()) { - mCode += newLineIfNeeded() - + code; + addCode(code); } } @@ -694,45 +709,38 @@ void Generator::GeneratorImpl::addImplementationCreateDeleteArrayMethodsCode() { if (modelHasOdes(mAnalyserModel) && !mProfile->implementationCreateStatesArrayMethodString().empty()) { - mCode += newLineIfNeeded() - + mProfile->implementationCreateStatesArrayMethodString(); + addCode(mProfile->implementationCreateStatesArrayMethodString()); } if (!mProfile->implementationCreateConstantsArrayMethodString().empty()) { - mCode += newLineIfNeeded() - + mProfile->implementationCreateConstantsArrayMethodString(); + addCode(mProfile->implementationCreateConstantsArrayMethodString()); } if (!mProfile->implementationCreateComputedConstantsArrayMethodString().empty()) { - mCode += newLineIfNeeded() - + mProfile->implementationCreateComputedConstantsArrayMethodString(); + addCode(mProfile->implementationCreateComputedConstantsArrayMethodString()); } if (!mProfile->implementationCreateAlgebraicVariablesArrayMethodString().empty()) { - mCode += newLineIfNeeded() - + mProfile->implementationCreateAlgebraicVariablesArrayMethodString(); + addCode(mProfile->implementationCreateAlgebraicVariablesArrayMethodString()); } if (mAnalyserModel->hasExternalVariables() && !mProfile->implementationCreateExternalVariablesArrayMethodString().empty()) { - mCode += newLineIfNeeded() - + mProfile->implementationCreateExternalVariablesArrayMethodString(); + addCode(mProfile->implementationCreateExternalVariablesArrayMethodString()); } if (!mProfile->implementationDeleteArrayMethodString().empty()) { - mCode += newLineIfNeeded() - + mProfile->implementationDeleteArrayMethodString(); + addCode(mProfile->implementationDeleteArrayMethodString()); } } void Generator::GeneratorImpl::addExternalVariableMethodTypeDefinitionCode() { if (mAnalyserModel->hasExternalVariables()) { - auto externalVariableMethodTypeDefinitionString = mProfile->externalVariableMethodTypeDefinitionString(modelHasOdes(mAnalyserModel)); + const auto &externalVariableMethodTypeDefinitionString = mProfile->externalVariableMethodTypeDefinitionString(modelHasOdes(mAnalyserModel)); if (!externalVariableMethodTypeDefinitionString.empty()) { - mCode += newLineIfNeeded() - + externalVariableMethodTypeDefinitionString; + addCode(externalVariableMethodTypeDefinitionString); } } } @@ -740,16 +748,14 @@ void Generator::GeneratorImpl::addExternalVariableMethodTypeDefinitionCode() void Generator::GeneratorImpl::addRootFindingInfoObjectCode() { if (!mProfile->rootFindingInfoObjectString(modelHasOdes(mAnalyserModel), mAnalyserModel->hasExternalVariables()).empty()) { - mCode += newLineIfNeeded() - + mProfile->rootFindingInfoObjectString(modelHasOdes(mAnalyserModel), mAnalyserModel->hasExternalVariables()); + addCode(mProfile->rootFindingInfoObjectString(modelHasOdes(mAnalyserModel), mAnalyserModel->hasExternalVariables())); } } void Generator::GeneratorImpl::addExternNlaSolveMethodCode() { if (!mProfile->externNlaSolveMethodString().empty()) { - mCode += newLineIfNeeded() - + mProfile->externNlaSolveMethodString(); + addCode(mProfile->externNlaSolveMethodString()); } } @@ -761,11 +767,11 @@ void Generator::GeneratorImpl::addNlaSystemsCode() // Note: only states and algebraic variables can be computed through an NLA system. Constants, computed // constants, and external variables cannot, by definition, be computed through an NLA system. - std::vector handledNlaAnalyserEquations; + std::unordered_set handledNlaAnalyserEquations; for (const auto &analyserEquation : mAnalyserModel->analyserEquations()) { if ((analyserEquation->type() == AnalyserEquation::Type::NLA) - && (std::find(handledNlaAnalyserEquations.begin(), handledNlaAnalyserEquations.end(), analyserEquation) == handledNlaAnalyserEquations.end())) { + && (handledNlaAnalyserEquations.find(analyserEquation.get()) == handledNlaAnalyserEquations.end())) { // 1) Generate some code for the objectiveFunction[INDEX]() method. // a) Retrieve the values from our NLA solver's u array. @@ -773,6 +779,8 @@ void Generator::GeneratorImpl::addNlaSystemsCode() auto i = MAX_SIZE_T; auto analyserVariables = libcellml::analyserVariables(analyserEquation); + methodBody.reserve(analyserVariables.size() * 256 + 512); + for (const auto &analyserVariable : analyserVariables) { auto arrayString = (analyserVariable->type() == AnalyserVariable::Type::STATE) ? mProfile->ratesArrayString() : @@ -798,9 +806,10 @@ void Generator::GeneratorImpl::addNlaSystemsCode() } } - std::vector dummyRemainingAnalyserEquations = mAnalyserModel->analyserEquations(); - std::vector dummyAnalyserEquationsForDependencies; - std::vector dummyGeneratedConstantDependencies; + const auto &analyserEquations = mAnalyserModel->analyserEquations(); + std::unordered_set dummyRemainingAnalyserEquations(analyserEquations.begin(), analyserEquations.end()); + std::unordered_set dummyAnalyserEquationsForDependencies; + std::unordered_set dummyGeneratedConstantDependencies; for (const auto &dependency : analyserEquation->dependencies()) { if (((dependency->type() == AnalyserEquation::Type::COMPUTED_CONSTANT) @@ -825,7 +834,7 @@ void Generator::GeneratorImpl::addNlaSystemsCode() + generateCode(analyserEquation->ast()) + mProfile->commandSeparatorString() + "\n"; - handledNlaAnalyserEquations.push_back(analyserEquation); + handledNlaAnalyserEquations.insert(analyserEquation.get()); for (const auto &nlaSibling : analyserEquation->nlaSiblings()) { methodBody += mProfile->indentString() @@ -834,19 +843,20 @@ void Generator::GeneratorImpl::addNlaSystemsCode() + generateCode(nlaSibling->ast()) + mProfile->commandSeparatorString() + "\n"; - handledNlaAnalyserEquations.push_back(nlaSibling); + handledNlaAnalyserEquations.insert(nlaSibling.get()); } - mCode += newLineIfNeeded() - + replace(replace(mProfile->objectiveFunctionMethodString(modelHasOdes(mAnalyserModel), mAnalyserModel->hasExternalVariables()), - "[INDEX]", convertToString(analyserEquation->nlaSystemIndex())), - "[CODE]", generateMethodBodyCode(methodBody)); + addCode(replace(replace(mProfile->objectiveFunctionMethodString(modelHasOdes(mAnalyserModel), mAnalyserModel->hasExternalVariables()), + "[INDEX]", convertToString(analyserEquation->nlaSystemIndex())), + "[CODE]", generateMethodBodyCode(methodBody))); // 2) Generate some code for the findRoot[INDEX]() method. // a) Assign the values to our NLA solver's u array. methodBody = {}; + methodBody.reserve(analyserVariables.size() * 192 + 256); + i = MAX_SIZE_T; for (const auto &analyserVariable : analyserVariables) { @@ -889,11 +899,10 @@ void Generator::GeneratorImpl::addNlaSystemsCode() + mProfile->commandSeparatorString() + "\n"; } - mCode += newLineIfNeeded() - + replace(replace(replace(mProfile->findRootMethodString(modelHasOdes(mAnalyserModel), mAnalyserModel->hasExternalVariables()), - "[INDEX]", convertToString(analyserEquation->nlaSystemIndex())), - "[SIZE]", convertToString(analyserVariablesCount)), - "[CODE]", generateMethodBodyCode(methodBody)); + addCode(replace(replace(replace(mProfile->findRootMethodString(modelHasOdes(mAnalyserModel), mAnalyserModel->hasExternalVariables()), + "[INDEX]", convertToString(analyserEquation->nlaSystemIndex())), + "[SIZE]", convertToString(analyserVariablesCount)), + "[CODE]", generateMethodBodyCode(methodBody))); } } } @@ -972,7 +981,9 @@ std::string Generator::GeneratorImpl::generateVariableNameCode(const VariablePtr } if (isTrackedVariable(analyserVariable, false)) { - return owningComponent(analyserVariable->variable())->name() + "_" + analyserVariable->variable()->name(); + const auto &var = analyserVariable->variable(); + + return owningComponent(var)->name() + "_" + var->name(); } std::string arrayName; @@ -998,7 +1009,6 @@ std::string Generator::GeneratorImpl::generateOperatorCode(const std::string &op { // Generate the code for the left and right branches of the given AST. - std::string res; auto astLeftChild = ast->leftChild(); auto astRightChild = ast->rightChild(); auto astLeftChildCode = generateCode(astLeftChild); @@ -1024,19 +1034,22 @@ std::string Generator::GeneratorImpl::generateOperatorCode(const std::string &op if (isRelationalOperator(astLeftChild) || isLogicalOperator(astLeftChild) || isPiecewiseStatement(astLeftChild)) { - astLeftChildCode = "(" + astLeftChildCode + ")"; + astLeftChildCode.insert(0, "("); + astLeftChildCode += ')'; } if (isRelationalOperator(astRightChild) || isLogicalOperator(astRightChild) || isPiecewiseStatement(astRightChild)) { - astRightChildCode = "(" + astRightChildCode + ")"; + astRightChildCode.insert(0, "("); + astRightChildCode += ')'; } } else if (isMinusOperator(ast)) { if (isRelationalOperator(astLeftChild) || isLogicalOperator(astLeftChild) || isPiecewiseStatement(astLeftChild)) { - astLeftChildCode = "(" + astLeftChildCode + ")"; + astLeftChildCode.insert(0, "("); + astLeftChildCode += ')'; } if (isNegativeNumber(astRightChild) @@ -1045,43 +1058,51 @@ std::string Generator::GeneratorImpl::generateOperatorCode(const std::string &op || isMinusOperator(astRightChild) || isPiecewiseStatement(astRightChild) || (astRightChildCode.rfind(mProfile->minusString(), 0) == 0)) { - astRightChildCode = "(" + astRightChildCode + ")"; + astRightChildCode.insert(0, "("); + astRightChildCode += ')'; } else if (isPlusOperator(astRightChild)) { if (astRightChild->rightChild() != nullptr) { - astRightChildCode = "(" + astRightChildCode + ")"; + astRightChildCode.insert(0, "("); + astRightChildCode += ')'; } } } else if (isTimesOperator(ast)) { if (isRelationalOperator(astLeftChild) || isLogicalOperator(astLeftChild) || isPiecewiseStatement(astLeftChild)) { - astLeftChildCode = "(" + astLeftChildCode + ")"; + astLeftChildCode.insert(0, "("); + astLeftChildCode += ')'; } else if (isPlusOperator(astLeftChild) || isMinusOperator(astLeftChild)) { if (astLeftChild->rightChild() != nullptr) { - astLeftChildCode = "(" + astLeftChildCode + ")"; + astLeftChildCode.insert(0, "("); + astLeftChildCode += ')'; } } if (isRelationalOperator(astRightChild) || isLogicalOperator(astRightChild) || isPiecewiseStatement(astRightChild)) { - astRightChildCode = "(" + astRightChildCode + ")"; + astRightChildCode.insert(0, "("); + astRightChildCode += ')'; } else if (isPlusOperator(astRightChild) || isMinusOperator(astRightChild)) { if (astRightChild->rightChild() != nullptr) { - astRightChildCode = "(" + astRightChildCode + ")"; + astRightChildCode.insert(0, "("); + astRightChildCode += ')'; } } } else if (isDivideOperator(ast)) { if (isRelationalOperator(astLeftChild) || isLogicalOperator(astLeftChild) || isPiecewiseStatement(astLeftChild)) { - astLeftChildCode = "(" + astLeftChildCode + ")"; + astLeftChildCode.insert(0, "("); + astLeftChildCode += ')'; } else if (isPlusOperator(astLeftChild) || isMinusOperator(astLeftChild)) { if (astLeftChild->rightChild() != nullptr) { - astLeftChildCode = "(" + astLeftChildCode + ")"; + astLeftChildCode.insert(0, "("); + astLeftChildCode += ')'; } } @@ -1090,11 +1111,13 @@ std::string Generator::GeneratorImpl::generateOperatorCode(const std::string &op || isTimesOperator(astRightChild) || isDivideOperator(astRightChild) || isPiecewiseStatement(astRightChild)) { - astRightChildCode = "(" + astRightChildCode + ")"; + astRightChildCode.insert(0, "("); + astRightChildCode += ')'; } else if (isPlusOperator(astRightChild) || isMinusOperator(astRightChild)) { if (astRightChild->rightChild() != nullptr) { - astRightChildCode = "(" + astRightChildCode + ")"; + astRightChildCode.insert(0, "("); + astRightChildCode += ')'; } } } else if (isAndOperator(ast)) { @@ -1107,32 +1130,40 @@ std::string Generator::GeneratorImpl::generateOperatorCode(const std::string &op || isOrOperator(astLeftChild) || isXorOperator(astLeftChild) || isPiecewiseStatement(astLeftChild)) { - astLeftChildCode = "(" + astLeftChildCode + ")"; + astLeftChildCode.insert(0, "("); + astLeftChildCode += ')'; } else if (isPlusOperator(astLeftChild) || isMinusOperator(astLeftChild)) { if (astLeftChild->rightChild() != nullptr) { - astLeftChildCode = "(" + astLeftChildCode + ")"; + astLeftChildCode.insert(0, "("); + astLeftChildCode += ')'; } } else if (isPowerOperator(astLeftChild)) { - astLeftChildCode = "(" + astLeftChildCode + ")"; + astLeftChildCode.insert(0, "("); + astLeftChildCode += ')'; } else if (isRootOperator(astLeftChild)) { - astLeftChildCode = "(" + astLeftChildCode + ")"; + astLeftChildCode.insert(0, "("); + astLeftChildCode += ')'; } if (isRelationalOperator(astRightChild) || isOrOperator(astRightChild) || isXorOperator(astRightChild) || isPiecewiseStatement(astRightChild)) { - astRightChildCode = "(" + astRightChildCode + ")"; + astRightChildCode.insert(0, "("); + astRightChildCode += ')'; } else if (isPlusOperator(astRightChild) || isMinusOperator(astRightChild)) { if (astRightChild->rightChild() != nullptr) { - astRightChildCode = "(" + astRightChildCode + ")"; + astRightChildCode.insert(0, "("); + astRightChildCode += ')'; } } else if (isPowerOperator(astRightChild)) { - astRightChildCode = "(" + astRightChildCode + ")"; + astRightChildCode.insert(0, "("); + astRightChildCode += ')'; } else if (isRootOperator(astRightChild)) { - astRightChildCode = "(" + astRightChildCode + ")"; + astRightChildCode.insert(0, "("); + astRightChildCode += ')'; } } else if (isOrOperator(ast)) { // Note: according to the precedence rules above, we only need to @@ -1144,32 +1175,40 @@ std::string Generator::GeneratorImpl::generateOperatorCode(const std::string &op || isAndOperator(astLeftChild) || isXorOperator(astLeftChild) || isPiecewiseStatement(astLeftChild)) { - astLeftChildCode = "(" + astLeftChildCode + ")"; + astLeftChildCode.insert(0, "("); + astLeftChildCode += ')'; } else if (isPlusOperator(astLeftChild) || isMinusOperator(astLeftChild)) { if (astLeftChild->rightChild() != nullptr) { - astLeftChildCode = "(" + astLeftChildCode + ")"; + astLeftChildCode.insert(0, "("); + astLeftChildCode += ')'; } } else if (isPowerOperator(astLeftChild)) { - astLeftChildCode = "(" + astLeftChildCode + ")"; + astLeftChildCode.insert(0, "("); + astLeftChildCode += ')'; } else if (isRootOperator(astLeftChild)) { - astLeftChildCode = "(" + astLeftChildCode + ")"; + astLeftChildCode.insert(0, "("); + astLeftChildCode += ')'; } if (isRelationalOperator(astRightChild) || isAndOperator(astRightChild) || isXorOperator(astRightChild) || isPiecewiseStatement(astRightChild)) { - astRightChildCode = "(" + astRightChildCode + ")"; + astRightChildCode.insert(0, "("); + astRightChildCode += ')'; } else if (isPlusOperator(astRightChild) || isMinusOperator(astRightChild)) { if (astRightChild->rightChild() != nullptr) { - astRightChildCode = "(" + astRightChildCode + ")"; + astRightChildCode.insert(0, "("); + astRightChildCode += ')'; } } else if (isPowerOperator(astRightChild)) { - astRightChildCode = "(" + astRightChildCode + ")"; + astRightChildCode.insert(0, "("); + astRightChildCode += ')'; } else if (isRootOperator(astRightChild)) { - astRightChildCode = "(" + astRightChildCode + ")"; + astRightChildCode.insert(0, "("); + astRightChildCode += ')'; } } else if (isXorOperator(ast)) { // Note: according to the precedence rules above, we only need to @@ -1181,32 +1220,40 @@ std::string Generator::GeneratorImpl::generateOperatorCode(const std::string &op || isAndOperator(astLeftChild) || isOrOperator(astLeftChild) || isPiecewiseStatement(astLeftChild)) { - astLeftChildCode = "(" + astLeftChildCode + ")"; + astLeftChildCode.insert(0, "("); + astLeftChildCode += ')'; } else if (isPlusOperator(astLeftChild) || isMinusOperator(astLeftChild)) { if (astLeftChild->rightChild() != nullptr) { - astLeftChildCode = "(" + astLeftChildCode + ")"; + astLeftChildCode.insert(0, "("); + astLeftChildCode += ')'; } } else if (isPowerOperator(astLeftChild)) { - astLeftChildCode = "(" + astLeftChildCode + ")"; + astLeftChildCode.insert(0, "("); + astLeftChildCode += ')'; } else if (isRootOperator(astLeftChild)) { - astLeftChildCode = "(" + astLeftChildCode + ")"; + astLeftChildCode.insert(0, "("); + astLeftChildCode += ')'; } if (isRelationalOperator(astRightChild) || isAndOperator(astRightChild) || isOrOperator(astRightChild) || isPiecewiseStatement(astRightChild)) { - astRightChildCode = "(" + astRightChildCode + ")"; + astRightChildCode.insert(0, "("); + astRightChildCode += ')'; } else if (isPlusOperator(astRightChild) || isMinusOperator(astRightChild)) { if (astRightChild->rightChild() != nullptr) { - astRightChildCode = "(" + astRightChildCode + ")"; + astRightChildCode.insert(0, "("); + astRightChildCode += ')'; } } else if (isPowerOperator(astRightChild)) { - astRightChildCode = "(" + astRightChildCode + ")"; + astRightChildCode.insert(0, "("); + astRightChildCode += ')'; } else if (isRootOperator(astRightChild)) { - astRightChildCode = "(" + astRightChildCode + ")"; + astRightChildCode.insert(0, "("); + astRightChildCode += ')'; } } else if (isPowerOperator(ast)) { if (isRelationalOperator(astLeftChild) @@ -1215,10 +1262,12 @@ std::string Generator::GeneratorImpl::generateOperatorCode(const std::string &op || isTimesOperator(astLeftChild) || isDivideOperator(astLeftChild) || isPiecewiseStatement(astLeftChild)) { - astLeftChildCode = "(" + astLeftChildCode + ")"; + astLeftChildCode.insert(0, "("); + astLeftChildCode += ')'; } else if (isPlusOperator(astLeftChild)) { if (astLeftChild->rightChild() != nullptr) { - astLeftChildCode = "(" + astLeftChildCode + ")"; + astLeftChildCode.insert(0, "("); + astLeftChildCode += ')'; } } @@ -1230,10 +1279,12 @@ std::string Generator::GeneratorImpl::generateOperatorCode(const std::string &op || isPowerOperator(astRightChild) || isRootOperator(astRightChild) || isPiecewiseStatement(astRightChild)) { - astRightChildCode = "(" + astRightChildCode + ")"; + astRightChildCode.insert(0, "("); + astRightChildCode += ')'; } else if (isPlusOperator(astRightChild)) { if (astRightChild->rightChild() != nullptr) { - astRightChildCode = "(" + astRightChildCode + ")"; + astRightChildCode.insert(0, "("); + astRightChildCode += ')'; } } } else if (isRootOperator(ast)) { @@ -1243,10 +1294,12 @@ std::string Generator::GeneratorImpl::generateOperatorCode(const std::string &op || isTimesOperator(astRightChild) || isDivideOperator(astRightChild) || isPiecewiseStatement(astRightChild)) { - astRightChildCode = "(" + astRightChildCode + ")"; + astRightChildCode.insert(0, "("); + astRightChildCode += ')'; } else if (isPlusOperator(astRightChild)) { if (astRightChild->rightChild() != nullptr) { - astRightChildCode = "(" + astRightChildCode + ")"; + astRightChildCode.insert(0, "("); + astRightChildCode += ')'; } } @@ -1260,17 +1313,37 @@ std::string Generator::GeneratorImpl::generateOperatorCode(const std::string &op || isPowerOperator(astLeftChildLeftChild) || isRootOperator(astLeftChildLeftChild) || isPiecewiseStatement(astLeftChildLeftChild)) { - astLeftChildCode = "(" + astLeftChildCode + ")"; + astLeftChildCode.insert(0, "("); + astLeftChildCode += ')'; } else if (isPlusOperator(astLeftChildLeftChild)) { if (astLeftChildLeftChild->rightChild() != nullptr) { - astLeftChildCode = "(" + astLeftChildCode + ")"; + astLeftChildCode.insert(0, "("); + astLeftChildCode += ')'; } } - return astRightChildCode + op + "(1.0/" + astLeftChildCode + ")"; + std::string res; + + res.reserve(astRightChildCode.size() + op.size() + 5 + astLeftChildCode.size() + 1); + + res += astRightChildCode; + res += op; + res += "(1.0/"; + res += astLeftChildCode; + res += ")"; + + return res; } - return astLeftChildCode + op + astRightChildCode; + std::string res; + + res.reserve(astLeftChildCode.size() + op.size() + astRightChildCode.size()); + + res += astLeftChildCode; + res += op; + res += astRightChildCode; + + return res; } std::string Generator::GeneratorImpl::generateMinusUnaryCode(const AnalyserEquationAstPtr &ast) @@ -1287,22 +1360,54 @@ std::string Generator::GeneratorImpl::generateMinusUnaryCode(const AnalyserEquat || isPlusOperator(astLeftChild) || isMinusOperator(astLeftChild) || isPiecewiseStatement(astLeftChild)) { - code = "(" + code + ")"; + code.insert(0, "("); + code += ')'; } - return mProfile->minusString() + code; + const auto &minusStr = mProfile->minusString(); + std::string res; + + res.reserve(minusStr.size() + code.size()); + + res += minusStr; + res += code; + + return res; } std::string Generator::GeneratorImpl::generateOneParameterFunctionCode(const std::string &function, const AnalyserEquationAstPtr &ast) { - return function + "(" + generateCode(ast->leftChild()) + ")"; + auto leftChildString = generateCode(ast->leftChild()); + std::string res; + + res.reserve(function.size() + 1 + leftChildString.size() + 1); + + res += function; + res += '('; + res += leftChildString; + res += ')'; + + return res; } std::string Generator::GeneratorImpl::generateTwoParameterFunctionCode(const std::string &function, const AnalyserEquationAstPtr &ast) { - return function + "(" + generateCode(ast->leftChild()) + ", " + generateCode(ast->rightChild()) + ")"; + auto leftChildString = generateCode(ast->leftChild()); + auto rightChildString = generateCode(ast->rightChild()); + std::string res; + + res.reserve(function.size() + 1 + leftChildString.size() + 2 + rightChildString.size() + 1); + + res += function; + res += '('; + res += leftChildString; + res += ", "; + res += rightChildString; + res += ')'; + + return res; } std::string Generator::GeneratorImpl::generatePiecewiseIfCode(const std::string &condition, @@ -1412,7 +1517,13 @@ std::string Generator::GeneratorImpl::generateCode(const AnalyserEquationAstPtr break; case AnalyserEquationAst::Type::NOT: if (mProfile->hasNotOperator()) { - code = mProfile->notString() + generateCode(ast->leftChild()); + auto leftChildString = generateCode(ast->leftChild()); + const auto ¬String = mProfile->notString(); + + code.reserve(notString.size() + leftChildString.size()); + + code += notString; + code += leftChildString; } else { code = generateOneParameterFunctionCode(mProfile->notString(), ast); } @@ -1453,9 +1564,21 @@ std::string Generator::GeneratorImpl::generateCode(const AnalyserEquationAstPtr && !mProfile->squareString().empty()) { code = generateOneParameterFunctionCode(mProfile->squareString(), ast); } else { - code = mProfile->hasPowerOperator() ? - generateOperatorCode(mProfile->powerString(), ast) : - mProfile->powerString() + "(" + generateCode(ast->leftChild()) + ", " + stringValue + ")"; + if (mProfile->hasPowerOperator()) { + code = generateOperatorCode(mProfile->powerString(), ast); + } else { + auto leftChildString = generateCode(ast->leftChild()); + const auto &powerString = mProfile->powerString(); + + code.reserve(powerString.size() + 1 + leftChildString.size() + 2 + stringValue.size() + 1); + + code += powerString; + code += '('; + code += leftChildString; + code += ", "; + code += stringValue; + code += ')'; + } } } break; case AnalyserEquationAst::Type::ROOT: { @@ -1467,7 +1590,15 @@ std::string Generator::GeneratorImpl::generateCode(const AnalyserEquationAstPtr if (convertToDouble(generateCode(astLeftChild), doubleValue) && areEqual(doubleValue, 2.0)) { - code = mProfile->squareRootString() + "(" + generateCode(astRightChild) + ")"; + auto rightChildString = generateCode(astRightChild); + const auto &squareRootString = mProfile->squareRootString(); + + code.reserve(squareRootString.size() + 1 + rightChildString.size() + 1); + + code += squareRootString; + code += '('; + code += rightChildString; + code += ')'; } else { if (mProfile->hasPowerOperator()) { code = generateOperatorCode(mProfile->powerString(), ast); @@ -1486,7 +1617,20 @@ std::string Generator::GeneratorImpl::generateCode(const AnalyserEquationAstPtr rootValueAst->setLeftChild(leftChild); rootValueAst->setRightChild(astLeftChild->leftChild()); - code = mProfile->powerString() + "(" + generateCode(astRightChild) + ", " + generateOperatorCode(mProfile->divideString(), rootValueAst) + ")"; + { + auto rightChildString = generateCode(astRightChild); + auto exponentString = generateOperatorCode(mProfile->divideString(), rootValueAst); + const auto &powerString = mProfile->powerString(); + + code.reserve(powerString.size() + 1 + rightChildString.size() + 2 + exponentString.size() + 1); + + code += powerString; + code += '('; + code += rightChildString; + code += ", "; + code += exponentString; + code += ')'; + } } } } else { @@ -1514,9 +1658,29 @@ std::string Generator::GeneratorImpl::generateCode(const AnalyserEquationAstPtr if (convertToDouble(stringValue, doubleValue) && areEqual(doubleValue, 10.0)) { - code = mProfile->commonLogarithmString() + "(" + generateCode(astRightChild) + ")"; + const auto &commonLogarithmString = mProfile->commonLogarithmString(); + auto rightChildString = generateCode(astRightChild); + + code.reserve(commonLogarithmString.size() + 1 + rightChildString.size() + 1); + + code += commonLogarithmString; + code += '('; + code += rightChildString; + code += ')'; } else { - code = mProfile->naturalLogarithmString() + "(" + generateCode(astRightChild) + ")/" + mProfile->naturalLogarithmString() + "(" + stringValue + ")"; + const auto &naturalLogarithmString = mProfile->naturalLogarithmString(); + auto rightChildString = generateCode(astRightChild); + + code.reserve(naturalLogarithmString.size() + 1 + rightChildString.size() + 2 + naturalLogarithmString.size() + 1 + stringValue.size() + 1); + + code += naturalLogarithmString; + code += '('; + code += rightChildString; + code += ")/"; + code += naturalLogarithmString; + code += '('; + code += stringValue; + code += ')'; } } else { code = generateOneParameterFunctionCode(mProfile->commonLogarithmString(), ast); @@ -1546,7 +1710,15 @@ std::string Generator::GeneratorImpl::generateCode(const AnalyserEquationAstPtr if (mAnalyserModel != nullptr) { code = generateCode(ast->rightChild()); } else { - code = "d" + generateCode(ast->rightChild()) + "/d" + generateCode(ast->leftChild()); + auto rightChildString = generateCode(ast->rightChild()); + auto leftChildString = generateCode(ast->leftChild()); + + code.reserve(1 + rightChildString.size() + 2 + leftChildString.size()); + + code = 'd'; + code += rightChildString; + code += "/d"; + code += leftChildString; } break; @@ -1698,27 +1870,27 @@ std::string Generator::GeneratorImpl::generateCode(const AnalyserEquationAstPtr break; case AnalyserEquationAst::Type::TRUE: - code = mProfile->trueString(); + code += mProfile->trueString(); break; case AnalyserEquationAst::Type::FALSE: - code = mProfile->falseString(); + code += mProfile->falseString(); break; case AnalyserEquationAst::Type::E: - code = mProfile->eString(); + code += mProfile->eString(); break; case AnalyserEquationAst::Type::PI: - code = mProfile->piString(); + code += mProfile->piString(); break; case AnalyserEquationAst::Type::INF: - code = mProfile->infString(); + code += mProfile->infString(); break; default: // AnalyserEquationAst::Type::NAN. - code = mProfile->nanString(); + code += mProfile->nanString(); break; } @@ -1791,29 +1963,28 @@ std::string Generator::GeneratorImpl::generateInitialisationCode(const AnalyserV code = replace(mProfile->variableDeclarationString(), "[CODE]", code); } - return mProfile->indentString() - + code; + return mProfile->indentString() + code; } std::string Generator::GeneratorImpl::generateEquationCode(const AnalyserEquationPtr &analyserEquation, - std::vector &remainingAnalyserEquations, - std::vector &analyserEquationsForDependencies, - std::vector &generatedConstantDependencies, + std::unordered_set &remainingAnalyserEquations, + std::unordered_set &analyserEquationsForDependencies, + std::unordered_set &generatedConstantDependencies, bool includeComputedConstants, GenerateEquationCodeTarget target) { std::string res; - if (std::find(remainingAnalyserEquations.begin(), remainingAnalyserEquations.end(), analyserEquation) != remainingAnalyserEquations.end()) { + if (remainingAnalyserEquations.count(analyserEquation) != 0) { // Stop tracking the analyser equation and its NLA siblings, if any. // Note: we need to do this as soon as possible to avoid recursive // calls, something that would happen if we were to do this at the // end of this if statement. - remainingAnalyserEquations.erase(std::find(remainingAnalyserEquations.begin(), remainingAnalyserEquations.end(), analyserEquation)); + remainingAnalyserEquations.erase(analyserEquation); for (const auto &nlaSibling : analyserEquation->nlaSiblings()) { - remainingAnalyserEquations.erase(std::find(remainingAnalyserEquations.begin(), remainingAnalyserEquations.end(), nlaSibling)); + remainingAnalyserEquations.erase(nlaSibling); } // Generate any dependency that this analyser equation may have. @@ -1821,10 +1992,10 @@ std::string Generator::GeneratorImpl::generateEquationCode(const AnalyserEquatio for (const auto &constantDependency : analyserEquation->mPimpl->mConstantDependencies) { if ((analyserEquation->type() != AnalyserEquation::Type::NLA) && isTrackedVariable(constantDependency, false) - && (std::find(generatedConstantDependencies.begin(), generatedConstantDependencies.end(), constantDependency) == generatedConstantDependencies.end())) { + && (generatedConstantDependencies.count(constantDependency) == 0)) { res += generateInitialisationCode(constantDependency, true); - generatedConstantDependencies.push_back(constantDependency); + generatedConstantDependencies.insert(constantDependency); } } @@ -1837,14 +2008,14 @@ std::string Generator::GeneratorImpl::generateEquationCode(const AnalyserEquatio || ((target == GenerateEquationCodeTarget::COMPUTE_VARIABLES) && ((dependency->type() != AnalyserEquation::Type::NLA) || isToBeComputedAgain(dependency) - || (std::find(analyserEquationsForDependencies.begin(), analyserEquationsForDependencies.end(), dependency) != analyserEquationsForDependencies.end())))) + || (analyserEquationsForDependencies.count(dependency) != 0)))) && (dependency->type() != AnalyserEquation::Type::ODE) && (isTrackedEquation(dependency, true) || (analyserEquation->type() != AnalyserEquation::Type::NLA)) && !isSomeConstant(dependency, includeComputedConstants) && (analyserEquationsForDependencies.empty() || isToBeComputedAgain(dependency) - || (std::find(analyserEquationsForDependencies.begin(), analyserEquationsForDependencies.end(), dependency) != analyserEquationsForDependencies.end())))) { + || (analyserEquationsForDependencies.count(dependency) != 0)))) { res += generateEquationCode(dependency, remainingAnalyserEquations, analyserEquationsForDependencies, generatedConstantDependencies, includeComputedConstants, target); } @@ -1885,10 +2056,10 @@ std::string Generator::GeneratorImpl::generateEquationCode(const AnalyserEquatio } std::string Generator::GeneratorImpl::generateEquationCode(const AnalyserEquationPtr &analyserEquation, - std::vector &remainingAnalyserEquations, - std::vector &generatedConstantDependencies) + std::unordered_set &remainingAnalyserEquations, + std::unordered_set &generatedConstantDependencies) { - std::vector dummyAnalyserEquationsForComputeVariables; + std::unordered_set dummyAnalyserEquationsForComputeVariables; return generateEquationCode(analyserEquation, remainingAnalyserEquations, dummyAnalyserEquationsForComputeVariables, generatedConstantDependencies, true); @@ -1913,12 +2084,12 @@ bool Generator::GeneratorImpl::hasComputedConstantDependency(const AnalyserVaria } std::string Generator::GeneratorImpl::generateInitialiseVariableCode(const AnalyserVariablePtr &analyserVariable, - std::vector &remainingAnalyserEquations, + std::unordered_set &remainingAnalyserEquations, std::vector &remainingStates, std::vector &remainingConstants, std::vector &remainingComputedConstants, std::vector &remainingAlgebraicVariables, - std::vector *generatedConstantDependencies) + std::unordered_set *generatedConstantDependencies) { std::string res; @@ -1987,38 +2158,39 @@ std::string Generator::GeneratorImpl::generateInitialiseVariableCode(const Analy void Generator::GeneratorImpl::addInterfaceComputeModelMethodsCode() { - auto interfaceInitialiseArraysMethodString = mProfile->interfaceInitialiseArraysMethodString(modelHasOdes(mAnalyserModel)); + const auto &interfaceInitialiseArraysMethodString = mProfile->interfaceInitialiseArraysMethodString(modelHasOdes(mAnalyserModel)); std::string code; if (!interfaceInitialiseArraysMethodString.empty()) { code += interfaceInitialiseArraysMethodString; } - if (!mProfile->interfaceComputeComputedConstantsMethodString(modelHasOdes(mAnalyserModel)).empty()) { - code += mProfile->interfaceComputeComputedConstantsMethodString(modelHasOdes(mAnalyserModel)); + const auto &interfaceComputeComputedConstantsMethodString = mProfile->interfaceComputeComputedConstantsMethodString(modelHasOdes(mAnalyserModel)); + + if (!interfaceComputeComputedConstantsMethodString.empty()) { + code += interfaceComputeComputedConstantsMethodString; } - auto interfaceComputeRatesMethodString = mProfile->interfaceComputeRatesMethodString(mAnalyserModel->hasExternalVariables()); + const auto &interfaceComputeRatesMethodString = mProfile->interfaceComputeRatesMethodString(mAnalyserModel->hasExternalVariables()); if (modelHasOdes(mAnalyserModel) && !interfaceComputeRatesMethodString.empty()) { code += interfaceComputeRatesMethodString; } - auto interfaceComputeVariablesMethodString = mProfile->interfaceComputeVariablesMethodString(modelHasOdes(mAnalyserModel), - mAnalyserModel->hasExternalVariables()); + const auto &interfaceComputeVariablesMethodString = mProfile->interfaceComputeVariablesMethodString(modelHasOdes(mAnalyserModel), + mAnalyserModel->hasExternalVariables()); if (!interfaceComputeVariablesMethodString.empty()) { code += interfaceComputeVariablesMethodString; } if (!code.empty()) { - mCode += newLineIfNeeded() - + code; + addCode(code); } } -void Generator::GeneratorImpl::addImplementationInitialiseArraysMethodCode(std::vector &remainingAnalyserEquations, +void Generator::GeneratorImpl::addImplementationInitialiseArraysMethodCode(std::unordered_set &remainingAnalyserEquations, std::vector &remainingStates, std::vector &remainingConstants, std::vector &remainingComputedConstants, @@ -2057,7 +2229,7 @@ void Generator::GeneratorImpl::addImplementationInitialiseArraysMethodCode(std:: // Initialise our computed constants that are initialised using an equation (e.g., x = 3 rather than x with an // initial value of 3). - std::vector generatedConstantDependencies; + std::unordered_set generatedConstantDependencies; for (const auto &equation : mAnalyserModel->analyserEquations()) { if (equation->type() == AnalyserEquation::Type::CONSTANT) { @@ -2084,26 +2256,27 @@ void Generator::GeneratorImpl::addImplementationInitialiseArraysMethodCode(std:: // Generate the method itself, if needed. - auto implementationInitialiseArraysMethodString = mProfile->implementationInitialiseArraysMethodString(modelHasOdes(mAnalyserModel)); + const auto &implementationInitialiseArraysMethodString = mProfile->implementationInitialiseArraysMethodString(modelHasOdes(mAnalyserModel)); if (!implementationInitialiseArraysMethodString.empty()) { - mCode += newLineIfNeeded() - + replace(implementationInitialiseArraysMethodString, - "[CODE]", generateMethodBodyCode(methodBody)); + addCode(replace(implementationInitialiseArraysMethodString, + "[CODE]", generateMethodBodyCode(methodBody))); } } -void Generator::GeneratorImpl::addImplementationComputeComputedConstantsMethodCode(std::vector &remainingAnalyserEquations, +void Generator::GeneratorImpl::addImplementationComputeComputedConstantsMethodCode(std::unordered_set &remainingAnalyserEquations, std::vector &remainingStates, std::vector &remainingConstants, std::vector &remainingComputedConstants, std::vector &remainingAlgebraicVariables) { - if (!mProfile->implementationComputeComputedConstantsMethodString(modelHasOdes(mAnalyserModel)).empty()) { + const auto &implementationComputeComputedConstantsMethodString = mProfile->implementationComputeComputedConstantsMethodString(modelHasOdes(mAnalyserModel)); + + if (!implementationComputeComputedConstantsMethodString.empty()) { // Initialise our remaining states (which are initialised using a computed constant). std::string methodBody; - std::vector generatedConstantDependencies; + std::unordered_set generatedConstantDependencies; for (const auto &state : mAnalyserModel->states()) { methodBody += generateInitialiseVariableCode(state, @@ -2135,20 +2308,19 @@ void Generator::GeneratorImpl::addImplementationComputeComputedConstantsMethodCo } } - mCode += newLineIfNeeded() - + replace(mProfile->implementationComputeComputedConstantsMethodString(modelHasOdes(mAnalyserModel)), - "[CODE]", generateMethodBodyCode(methodBody)); + addCode(replace(implementationComputeComputedConstantsMethodString, + "[CODE]", generateMethodBodyCode(methodBody))); } } -void Generator::GeneratorImpl::addImplementationComputeRatesMethodCode(std::vector &remainingAnalyserEquations) +void Generator::GeneratorImpl::addImplementationComputeRatesMethodCode(std::unordered_set &remainingAnalyserEquations) { - auto implementationComputeRatesMethodString = mProfile->implementationComputeRatesMethodString(mAnalyserModel->hasExternalVariables()); + const auto &implementationComputeRatesMethodString = mProfile->implementationComputeRatesMethodString(mAnalyserModel->hasExternalVariables()); if (modelHasOdes(mAnalyserModel) && !implementationComputeRatesMethodString.empty()) { std::string methodBody; - std::vector generatedConstantDependencies; + std::unordered_set generatedConstantDependencies; for (const auto &analyserEquation : mAnalyserModel->analyserEquations()) { // A rate is computed either through an ODE equation or through an @@ -2165,25 +2337,24 @@ void Generator::GeneratorImpl::addImplementationComputeRatesMethodCode(std::vect } } - mCode += newLineIfNeeded() - + replace(implementationComputeRatesMethodString, - "[CODE]", generateMethodBodyCode(methodBody)); + addCode(replace(implementationComputeRatesMethodString, + "[CODE]", generateMethodBodyCode(methodBody))); } } -void Generator::GeneratorImpl::addImplementationComputeVariablesMethodCode(std::vector &remainingAnalyserEquations) +void Generator::GeneratorImpl::addImplementationComputeVariablesMethodCode(std::unordered_set &remainingAnalyserEquations) { - auto implementationComputeVariablesMethodString = mProfile->implementationComputeVariablesMethodString(modelHasOdes(mAnalyserModel), - mAnalyserModel->hasExternalVariables()); + const auto &implementationComputeVariablesMethodString = mProfile->implementationComputeVariablesMethodString(modelHasOdes(mAnalyserModel), + mAnalyserModel->hasExternalVariables()); if (!implementationComputeVariablesMethodString.empty()) { std::string methodBody; - auto analyserEquations = mAnalyserModel->analyserEquations(); - auto newRemainingAnalyserEquations = analyserEquations; - std::vector generatedConstantDependencies; + const auto &analyserEquations = mAnalyserModel->analyserEquations(); + std::unordered_set newRemainingAnalyserEquations(analyserEquations.begin(), analyserEquations.end()); + std::unordered_set generatedConstantDependencies; for (const auto &analyserEquation : analyserEquations) { - if (((std::find(remainingAnalyserEquations.begin(), remainingAnalyserEquations.end(), analyserEquation) != remainingAnalyserEquations.end()) + if (((remainingAnalyserEquations.count(analyserEquation) != 0) || isToBeComputedAgain(analyserEquation)) && isTrackedEquation(analyserEquation, true)) { methodBody += generateEquationCode(analyserEquation, newRemainingAnalyserEquations, remainingAnalyserEquations, @@ -2192,9 +2363,8 @@ void Generator::GeneratorImpl::addImplementationComputeVariablesMethodCode(std:: } } - mCode += newLineIfNeeded() - + replace(implementationComputeVariablesMethodString, - "[CODE]", generateMethodBodyCode(methodBody)); + addCode(replace(implementationComputeVariablesMethodString, + "[CODE]", generateMethodBodyCode(methodBody))); } } @@ -2383,7 +2553,8 @@ std::string Generator::implementationCode(const AnalyserModelPtr &analyserModel, // Add code for the implementation to initialise our arrays. - auto remainingAnalyserEquations = pFunc()->mAnalyserModel->analyserEquations(); + const auto &analyserEquations = pFunc()->mAnalyserModel->analyserEquations(); + std::unordered_set remainingAnalyserEquations(analyserEquations.begin(), analyserEquations.end()); auto remainingStates = pFunc()->mAnalyserModel->states(); auto remainingConstants = pFunc()->mAnalyserModel->constants(); auto remainingComputedConstants = pFunc()->mAnalyserModel->computedConstants(); diff --git a/src/generator_p.h b/src/generator_p.h index 5c1a3f642..2bc0ae004 100644 --- a/src/generator_p.h +++ b/src/generator_p.h @@ -74,7 +74,7 @@ struct Generator::GeneratorImpl: public Logger::LoggerImpl bool modifiedProfile() const; - std::string newLineIfNeeded(); + void addCode(const std::string &code); void addOriginCommentCode(); @@ -138,36 +138,36 @@ struct Generator::GeneratorImpl: public Logger::LoggerImpl std::string generateZeroInitialisationCode(const AnalyserVariablePtr &analyserVariable); std::string generateInitialisationCode(const AnalyserVariablePtr &analyserVariable, bool force = false); std::string generateEquationCode(const AnalyserEquationPtr &analyserEquation, - std::vector &remainingAnalyserEquations, - std::vector &analyserEquationsForDependencies, - std::vector &generatedConstantDependencies, + std::unordered_set &remainingAnalyserEquations, + std::unordered_set &analyserEquationsForDependencies, + std::unordered_set &generatedConstantDependencies, bool includeComputedConstants, GenerateEquationCodeTarget target = GenerateEquationCodeTarget::NORMAL); std::string generateEquationCode(const AnalyserEquationPtr &analyserEquation, - std::vector &remainingAnalyserEquations, - std::vector &generatedConstantDependencies); + std::unordered_set &remainingAnalyserEquations, + std::unordered_set &generatedConstantDependencies); bool hasComputedConstantDependency(const AnalyserVariablePtr &analyserVariable); std::string generateInitialiseVariableCode(const AnalyserVariablePtr &analyserVariable, - std::vector &remainingAnalyserEquations, + std::unordered_set &remainingAnalyserEquations, std::vector &remainingStates, std::vector &remainingConstants, std::vector &remainingComputedConstants, std::vector &remainingAlgebraicVariables, - std::vector *generatedConstantDependencies = nullptr); + std::unordered_set *generatedConstantDependencies = nullptr); void addInterfaceComputeModelMethodsCode(); - void addImplementationInitialiseArraysMethodCode(std::vector &remainingAnalyserEquations, + void addImplementationInitialiseArraysMethodCode(std::unordered_set &remainingAnalyserEquations, std::vector &remainingStates, std::vector &remainingConstants, std::vector &remainingComputedConstants, std::vector &remainingAlgebraicVariables); - void addImplementationComputeComputedConstantsMethodCode(std::vector &remainingAnalyserEquations, + void addImplementationComputeComputedConstantsMethodCode(std::unordered_set &remainingAnalyserEquations, std::vector &remainingStates, std::vector &remainingConstants, std::vector &remainingComputedConstants, std::vector &remainingAlgebraicVariables); - void addImplementationComputeRatesMethodCode(std::vector &remainingAnalyserEquations); - void addImplementationComputeVariablesMethodCode(std::vector &remainingAnalyserEquations); + void addImplementationComputeRatesMethodCode(std::unordered_set &remainingAnalyserEquations); + void addImplementationComputeVariablesMethodCode(std::unordered_set &remainingAnalyserEquations); }; } // namespace libcellml diff --git a/src/generatorprofile.cpp b/src/generatorprofile.cpp index f4904a2f7..58005875c 100644 --- a/src/generatorprofile.cpp +++ b/src/generatorprofile.cpp @@ -1026,7 +1026,7 @@ void GeneratorProfile::setHasInterface(bool hasInterface) mPimpl->mHasInterface = hasInterface; } -std::string GeneratorProfile::equalityString() const +const std::string &GeneratorProfile::equalityString() const { return mPimpl->mEqualityString; } @@ -1036,7 +1036,7 @@ void GeneratorProfile::setEqualityString(const std::string &equalityString) mPimpl->mEqualityString = equalityString; } -std::string GeneratorProfile::eqString() const +const std::string &GeneratorProfile::eqString() const { return mPimpl->mEqString; } @@ -1046,7 +1046,7 @@ void GeneratorProfile::setEqString(const std::string &eqString) mPimpl->mEqString = eqString; } -std::string GeneratorProfile::neqString() const +const std::string &GeneratorProfile::neqString() const { return mPimpl->mNeqString; } @@ -1056,7 +1056,7 @@ void GeneratorProfile::setNeqString(const std::string &neqString) mPimpl->mNeqString = neqString; } -std::string GeneratorProfile::ltString() const +const std::string &GeneratorProfile::ltString() const { return mPimpl->mLtString; } @@ -1066,7 +1066,7 @@ void GeneratorProfile::setLtString(const std::string <String) mPimpl->mLtString = ltString; } -std::string GeneratorProfile::leqString() const +const std::string &GeneratorProfile::leqString() const { return mPimpl->mLeqString; } @@ -1076,7 +1076,7 @@ void GeneratorProfile::setLeqString(const std::string &leqString) mPimpl->mLeqString = leqString; } -std::string GeneratorProfile::gtString() const +const std::string &GeneratorProfile::gtString() const { return mPimpl->mGtString; } @@ -1086,7 +1086,7 @@ void GeneratorProfile::setGtString(const std::string >String) mPimpl->mGtString = gtString; } -std::string GeneratorProfile::geqString() const +const std::string &GeneratorProfile::geqString() const { return mPimpl->mGeqString; } @@ -1096,7 +1096,7 @@ void GeneratorProfile::setGeqString(const std::string &geqString) mPimpl->mGeqString = geqString; } -std::string GeneratorProfile::andString() const +const std::string &GeneratorProfile::andString() const { return mPimpl->mAndString; } @@ -1106,7 +1106,7 @@ void GeneratorProfile::setAndString(const std::string &andString) mPimpl->mAndString = andString; } -std::string GeneratorProfile::orString() const +const std::string &GeneratorProfile::orString() const { return mPimpl->mOrString; } @@ -1116,7 +1116,7 @@ void GeneratorProfile::setOrString(const std::string &orString) mPimpl->mOrString = orString; } -std::string GeneratorProfile::xorString() const +const std::string &GeneratorProfile::xorString() const { return mPimpl->mXorString; } @@ -1126,7 +1126,7 @@ void GeneratorProfile::setXorString(const std::string &xorString) mPimpl->mXorString = xorString; } -std::string GeneratorProfile::notString() const +const std::string &GeneratorProfile::notString() const { return mPimpl->mNotString; } @@ -1236,7 +1236,7 @@ void GeneratorProfile::setHasNotOperator(bool hasNotOperator) mPimpl->mHasNotOperator = hasNotOperator; } -std::string GeneratorProfile::plusString() const +const std::string &GeneratorProfile::plusString() const { return mPimpl->mPlusString; } @@ -1246,7 +1246,7 @@ void GeneratorProfile::setPlusString(const std::string &plusString) mPimpl->mPlusString = plusString; } -std::string GeneratorProfile::minusString() const +const std::string &GeneratorProfile::minusString() const { return mPimpl->mMinusString; } @@ -1256,7 +1256,7 @@ void GeneratorProfile::setMinusString(const std::string &minusString) mPimpl->mMinusString = minusString; } -std::string GeneratorProfile::timesString() const +const std::string &GeneratorProfile::timesString() const { return mPimpl->mTimesString; } @@ -1266,7 +1266,7 @@ void GeneratorProfile::setTimesString(const std::string ×String) mPimpl->mTimesString = timesString; } -std::string GeneratorProfile::divideString() const +const std::string &GeneratorProfile::divideString() const { return mPimpl->mDivideString; } @@ -1276,7 +1276,7 @@ void GeneratorProfile::setDivideString(const std::string ÷String) mPimpl->mDivideString = divideString; } -std::string GeneratorProfile::powerString() const +const std::string &GeneratorProfile::powerString() const { return mPimpl->mPowerString; } @@ -1286,7 +1286,7 @@ void GeneratorProfile::setPowerString(const std::string &powerString) mPimpl->mPowerString = powerString; } -std::string GeneratorProfile::squareRootString() const +const std::string &GeneratorProfile::squareRootString() const { return mPimpl->mSquareRootString; } @@ -1296,7 +1296,7 @@ void GeneratorProfile::setSquareRootString(const std::string &squareRootString) mPimpl->mSquareRootString = squareRootString; } -std::string GeneratorProfile::squareString() const +const std::string &GeneratorProfile::squareString() const { return mPimpl->mSquareString; } @@ -1306,7 +1306,7 @@ void GeneratorProfile::setSquareString(const std::string &squareString) mPimpl->mSquareString = squareString; } -std::string GeneratorProfile::absoluteValueString() const +const std::string &GeneratorProfile::absoluteValueString() const { return mPimpl->mAbsoluteValueString; } @@ -1316,7 +1316,7 @@ void GeneratorProfile::setAbsoluteValueString(const std::string &absoluteValueSt mPimpl->mAbsoluteValueString = absoluteValueString; } -std::string GeneratorProfile::exponentialString() const +const std::string &GeneratorProfile::exponentialString() const { return mPimpl->mExponentialString; } @@ -1326,7 +1326,7 @@ void GeneratorProfile::setExponentialString(const std::string &exponentialString mPimpl->mExponentialString = exponentialString; } -std::string GeneratorProfile::naturalLogarithmString() const +const std::string &GeneratorProfile::naturalLogarithmString() const { return mPimpl->mNaturalLogarithmString; } @@ -1336,7 +1336,7 @@ void GeneratorProfile::setNaturalLogarithmString(const std::string &naturalLogar mPimpl->mNaturalLogarithmString = naturalLogarithmString; } -std::string GeneratorProfile::commonLogarithmString() const +const std::string &GeneratorProfile::commonLogarithmString() const { return mPimpl->mCommonLogarithmString; } @@ -1346,7 +1346,7 @@ void GeneratorProfile::setCommonLogarithmString(const std::string &commonLogarit mPimpl->mCommonLogarithmString = commonLogarithmString; } -std::string GeneratorProfile::ceilingString() const +const std::string &GeneratorProfile::ceilingString() const { return mPimpl->mCeilingString; } @@ -1356,7 +1356,7 @@ void GeneratorProfile::setCeilingString(const std::string &ceilingString) mPimpl->mCeilingString = ceilingString; } -std::string GeneratorProfile::floorString() const +const std::string &GeneratorProfile::floorString() const { return mPimpl->mFloorString; } @@ -1366,7 +1366,7 @@ void GeneratorProfile::setFloorString(const std::string &floorString) mPimpl->mFloorString = floorString; } -std::string GeneratorProfile::minString() const +const std::string &GeneratorProfile::minString() const { return mPimpl->mMinString; } @@ -1376,7 +1376,7 @@ void GeneratorProfile::setMinString(const std::string &minString) mPimpl->mMinString = minString; } -std::string GeneratorProfile::maxString() const +const std::string &GeneratorProfile::maxString() const { return mPimpl->mMaxString; } @@ -1386,7 +1386,7 @@ void GeneratorProfile::setMaxString(const std::string &maxString) mPimpl->mMaxString = maxString; } -std::string GeneratorProfile::remString() const +const std::string &GeneratorProfile::remString() const { return mPimpl->mRemString; } @@ -1406,7 +1406,7 @@ void GeneratorProfile::setHasPowerOperator(bool hasPowerOperator) mPimpl->mHasPowerOperator = hasPowerOperator; } -std::string GeneratorProfile::sinString() const +const std::string &GeneratorProfile::sinString() const { return mPimpl->mSinString; } @@ -1416,7 +1416,7 @@ void GeneratorProfile::setSinString(const std::string &sinString) mPimpl->mSinString = sinString; } -std::string GeneratorProfile::cosString() const +const std::string &GeneratorProfile::cosString() const { return mPimpl->mCosString; } @@ -1426,7 +1426,7 @@ void GeneratorProfile::setCosString(const std::string &cosString) mPimpl->mCosString = cosString; } -std::string GeneratorProfile::tanString() const +const std::string &GeneratorProfile::tanString() const { return mPimpl->mTanString; } @@ -1436,7 +1436,7 @@ void GeneratorProfile::setTanString(const std::string &tanString) mPimpl->mTanString = tanString; } -std::string GeneratorProfile::secString() const +const std::string &GeneratorProfile::secString() const { return mPimpl->mSecString; } @@ -1446,7 +1446,7 @@ void GeneratorProfile::setSecString(const std::string &secString) mPimpl->mSecString = secString; } -std::string GeneratorProfile::cscString() const +const std::string &GeneratorProfile::cscString() const { return mPimpl->mCscString; } @@ -1456,7 +1456,7 @@ void GeneratorProfile::setCscString(const std::string &cscString) mPimpl->mCscString = cscString; } -std::string GeneratorProfile::cotString() const +const std::string &GeneratorProfile::cotString() const { return mPimpl->mCotString; } @@ -1466,7 +1466,7 @@ void GeneratorProfile::setCotString(const std::string &cotString) mPimpl->mCotString = cotString; } -std::string GeneratorProfile::sinhString() const +const std::string &GeneratorProfile::sinhString() const { return mPimpl->mSinhString; } @@ -1476,7 +1476,7 @@ void GeneratorProfile::setSinhString(const std::string &sinhString) mPimpl->mSinhString = sinhString; } -std::string GeneratorProfile::coshString() const +const std::string &GeneratorProfile::coshString() const { return mPimpl->mCoshString; } @@ -1486,7 +1486,7 @@ void GeneratorProfile::setCoshString(const std::string &coshString) mPimpl->mCoshString = coshString; } -std::string GeneratorProfile::tanhString() const +const std::string &GeneratorProfile::tanhString() const { return mPimpl->mTanhString; } @@ -1496,7 +1496,7 @@ void GeneratorProfile::setTanhString(const std::string &tanhString) mPimpl->mTanhString = tanhString; } -std::string GeneratorProfile::sechString() const +const std::string &GeneratorProfile::sechString() const { return mPimpl->mSechString; } @@ -1506,7 +1506,7 @@ void GeneratorProfile::setSechString(const std::string &sechString) mPimpl->mSechString = sechString; } -std::string GeneratorProfile::cschString() const +const std::string &GeneratorProfile::cschString() const { return mPimpl->mCschString; } @@ -1516,7 +1516,7 @@ void GeneratorProfile::setCschString(const std::string &cschString) mPimpl->mCschString = cschString; } -std::string GeneratorProfile::cothString() const +const std::string &GeneratorProfile::cothString() const { return mPimpl->mCothString; } @@ -1526,7 +1526,7 @@ void GeneratorProfile::setCothString(const std::string &cothString) mPimpl->mCothString = cothString; } -std::string GeneratorProfile::asinString() const +const std::string &GeneratorProfile::asinString() const { return mPimpl->mAsinString; } @@ -1536,7 +1536,7 @@ void GeneratorProfile::setAsinString(const std::string &asinString) mPimpl->mAsinString = asinString; } -std::string GeneratorProfile::acosString() const +const std::string &GeneratorProfile::acosString() const { return mPimpl->mAcosString; } @@ -1546,7 +1546,7 @@ void GeneratorProfile::setAcosString(const std::string &acosString) mPimpl->mAcosString = acosString; } -std::string GeneratorProfile::atanString() const +const std::string &GeneratorProfile::atanString() const { return mPimpl->mAtanString; } @@ -1556,7 +1556,7 @@ void GeneratorProfile::setAtanString(const std::string &atanString) mPimpl->mAtanString = atanString; } -std::string GeneratorProfile::asecString() const +const std::string &GeneratorProfile::asecString() const { return mPimpl->mAsecString; } @@ -1566,7 +1566,7 @@ void GeneratorProfile::setAsecString(const std::string &asecString) mPimpl->mAsecString = asecString; } -std::string GeneratorProfile::acscString() const +const std::string &GeneratorProfile::acscString() const { return mPimpl->mAcscString; } @@ -1576,7 +1576,7 @@ void GeneratorProfile::setAcscString(const std::string &acscString) mPimpl->mAcscString = acscString; } -std::string GeneratorProfile::acotString() const +const std::string &GeneratorProfile::acotString() const { return mPimpl->mAcotString; } @@ -1586,7 +1586,7 @@ void GeneratorProfile::setAcotString(const std::string &acotString) mPimpl->mAcotString = acotString; } -std::string GeneratorProfile::asinhString() const +const std::string &GeneratorProfile::asinhString() const { return mPimpl->mAsinhString; } @@ -1596,7 +1596,7 @@ void GeneratorProfile::setAsinhString(const std::string &asinhString) mPimpl->mAsinhString = asinhString; } -std::string GeneratorProfile::acoshString() const +const std::string &GeneratorProfile::acoshString() const { return mPimpl->mAcoshString; } @@ -1606,7 +1606,7 @@ void GeneratorProfile::setAcoshString(const std::string &acoshString) mPimpl->mAcoshString = acoshString; } -std::string GeneratorProfile::atanhString() const +const std::string &GeneratorProfile::atanhString() const { return mPimpl->mAtanhString; } @@ -1616,7 +1616,7 @@ void GeneratorProfile::setAtanhString(const std::string &atanhString) mPimpl->mAtanhString = atanhString; } -std::string GeneratorProfile::asechString() const +const std::string &GeneratorProfile::asechString() const { return mPimpl->mAsechString; } @@ -1626,7 +1626,7 @@ void GeneratorProfile::setAsechString(const std::string &asechString) mPimpl->mAsechString = asechString; } -std::string GeneratorProfile::acschString() const +const std::string &GeneratorProfile::acschString() const { return mPimpl->mAcschString; } @@ -1636,7 +1636,7 @@ void GeneratorProfile::setAcschString(const std::string &acschString) mPimpl->mAcschString = acschString; } -std::string GeneratorProfile::acothString() const +const std::string &GeneratorProfile::acothString() const { return mPimpl->mAcothString; } @@ -1646,7 +1646,7 @@ void GeneratorProfile::setAcothString(const std::string &acothString) mPimpl->mAcothString = acothString; } -std::string GeneratorProfile::conditionalOperatorIfString() const +const std::string &GeneratorProfile::conditionalOperatorIfString() const { return mPimpl->mConditionalOperatorIfString; } @@ -1656,7 +1656,7 @@ void GeneratorProfile::setConditionalOperatorIfString(const std::string &conditi mPimpl->mConditionalOperatorIfString = conditionalOperatorIfString; } -std::string GeneratorProfile::conditionalOperatorElseString() const +const std::string &GeneratorProfile::conditionalOperatorElseString() const { return mPimpl->mConditionalOperatorElseString; } @@ -1666,7 +1666,7 @@ void GeneratorProfile::setConditionalOperatorElseString(const std::string &condi mPimpl->mConditionalOperatorElseString = conditionalOperatorElseString; } -std::string GeneratorProfile::piecewiseIfString() const +const std::string &GeneratorProfile::piecewiseIfString() const { return mPimpl->mPiecewiseIfString; } @@ -1676,7 +1676,7 @@ void GeneratorProfile::setPiecewiseIfString(const std::string &piecewiseIfString mPimpl->mPiecewiseIfString = piecewiseIfString; } -std::string GeneratorProfile::piecewiseElseString() const +const std::string &GeneratorProfile::piecewiseElseString() const { return mPimpl->mPiecewiseElseString; } @@ -1696,7 +1696,7 @@ void GeneratorProfile::setHasConditionalOperator(bool hasConditionalOperator) mPimpl->mHasConditionalOperator = hasConditionalOperator; } -std::string GeneratorProfile::trueString() const +const std::string &GeneratorProfile::trueString() const { return mPimpl->mTrueString; } @@ -1706,7 +1706,7 @@ void GeneratorProfile::setTrueString(const std::string &trueString) mPimpl->mTrueString = trueString; } -std::string GeneratorProfile::falseString() const +const std::string &GeneratorProfile::falseString() const { return mPimpl->mFalseString; } @@ -1716,7 +1716,7 @@ void GeneratorProfile::setFalseString(const std::string &falseString) mPimpl->mFalseString = falseString; } -std::string GeneratorProfile::eString() const +const std::string &GeneratorProfile::eString() const { return mPimpl->mEString; } @@ -1726,7 +1726,7 @@ void GeneratorProfile::setEString(const std::string &eString) mPimpl->mEString = eString; } -std::string GeneratorProfile::piString() const +const std::string &GeneratorProfile::piString() const { return mPimpl->mPiString; } @@ -1736,7 +1736,7 @@ void GeneratorProfile::setPiString(const std::string &piString) mPimpl->mPiString = piString; } -std::string GeneratorProfile::infString() const +const std::string &GeneratorProfile::infString() const { return mPimpl->mInfString; } @@ -1746,7 +1746,7 @@ void GeneratorProfile::setInfString(const std::string &infString) mPimpl->mInfString = infString; } -std::string GeneratorProfile::nanString() const +const std::string &GeneratorProfile::nanString() const { return mPimpl->mNanString; } @@ -1756,7 +1756,7 @@ void GeneratorProfile::setNanString(const std::string &nanString) mPimpl->mNanString = nanString; } -std::string GeneratorProfile::eqFunctionString() const +const std::string &GeneratorProfile::eqFunctionString() const { return mPimpl->mEqFunctionString; } @@ -1766,7 +1766,7 @@ void GeneratorProfile::setEqFunctionString(const std::string &eqFunctionString) mPimpl->mEqFunctionString = eqFunctionString; } -std::string GeneratorProfile::neqFunctionString() const +const std::string &GeneratorProfile::neqFunctionString() const { return mPimpl->mNeqFunctionString; } @@ -1776,7 +1776,7 @@ void GeneratorProfile::setNeqFunctionString(const std::string &neqFunctionString mPimpl->mNeqFunctionString = neqFunctionString; } -std::string GeneratorProfile::ltFunctionString() const +const std::string &GeneratorProfile::ltFunctionString() const { return mPimpl->mLtFunctionString; } @@ -1786,7 +1786,7 @@ void GeneratorProfile::setLtFunctionString(const std::string <FunctionString) mPimpl->mLtFunctionString = ltFunctionString; } -std::string GeneratorProfile::leqFunctionString() const +const std::string &GeneratorProfile::leqFunctionString() const { return mPimpl->mLeqFunctionString; } @@ -1796,7 +1796,7 @@ void GeneratorProfile::setLeqFunctionString(const std::string &leqFunctionString mPimpl->mLeqFunctionString = leqFunctionString; } -std::string GeneratorProfile::gtFunctionString() const +const std::string &GeneratorProfile::gtFunctionString() const { return mPimpl->mGtFunctionString; } @@ -1806,7 +1806,7 @@ void GeneratorProfile::setGtFunctionString(const std::string >FunctionString) mPimpl->mGtFunctionString = gtFunctionString; } -std::string GeneratorProfile::geqFunctionString() const +const std::string &GeneratorProfile::geqFunctionString() const { return mPimpl->mGeqFunctionString; } @@ -1816,7 +1816,7 @@ void GeneratorProfile::setGeqFunctionString(const std::string &geqFunctionString mPimpl->mGeqFunctionString = geqFunctionString; } -std::string GeneratorProfile::andFunctionString() const +const std::string &GeneratorProfile::andFunctionString() const { return mPimpl->mAndFunctionString; } @@ -1826,7 +1826,7 @@ void GeneratorProfile::setAndFunctionString(const std::string &andFunctionString mPimpl->mAndFunctionString = andFunctionString; } -std::string GeneratorProfile::orFunctionString() const +const std::string &GeneratorProfile::orFunctionString() const { return mPimpl->mOrFunctionString; } @@ -1836,7 +1836,7 @@ void GeneratorProfile::setOrFunctionString(const std::string &orFunctionString) mPimpl->mOrFunctionString = orFunctionString; } -std::string GeneratorProfile::xorFunctionString() const +const std::string &GeneratorProfile::xorFunctionString() const { return mPimpl->mXorFunctionString; } @@ -1846,7 +1846,7 @@ void GeneratorProfile::setXorFunctionString(const std::string &xorFunctionString mPimpl->mXorFunctionString = xorFunctionString; } -std::string GeneratorProfile::notFunctionString() const +const std::string &GeneratorProfile::notFunctionString() const { return mPimpl->mNotFunctionString; } @@ -1856,7 +1856,7 @@ void GeneratorProfile::setNotFunctionString(const std::string ¬FunctionString mPimpl->mNotFunctionString = notFunctionString; } -std::string GeneratorProfile::minFunctionString() const +const std::string &GeneratorProfile::minFunctionString() const { return mPimpl->mMinFunctionString; } @@ -1866,7 +1866,7 @@ void GeneratorProfile::setMinFunctionString(const std::string &minFunctionString mPimpl->mMinFunctionString = minFunctionString; } -std::string GeneratorProfile::maxFunctionString() const +const std::string &GeneratorProfile::maxFunctionString() const { return mPimpl->mMaxFunctionString; } @@ -1876,7 +1876,7 @@ void GeneratorProfile::setMaxFunctionString(const std::string &maxFunctionString mPimpl->mMaxFunctionString = maxFunctionString; } -std::string GeneratorProfile::secFunctionString() const +const std::string &GeneratorProfile::secFunctionString() const { return mPimpl->mSecFunctionString; } @@ -1886,7 +1886,7 @@ void GeneratorProfile::setSecFunctionString(const std::string &secFunctionString mPimpl->mSecFunctionString = secFunctionString; } -std::string GeneratorProfile::cscFunctionString() const +const std::string &GeneratorProfile::cscFunctionString() const { return mPimpl->mCscFunctionString; } @@ -1896,7 +1896,7 @@ void GeneratorProfile::setCscFunctionString(const std::string &cscFunctionString mPimpl->mCscFunctionString = cscFunctionString; } -std::string GeneratorProfile::cotFunctionString() const +const std::string &GeneratorProfile::cotFunctionString() const { return mPimpl->mCotFunctionString; } @@ -1906,7 +1906,7 @@ void GeneratorProfile::setCotFunctionString(const std::string &cotFunctionString mPimpl->mCotFunctionString = cotFunctionString; } -std::string GeneratorProfile::sechFunctionString() const +const std::string &GeneratorProfile::sechFunctionString() const { return mPimpl->mSechFunctionString; } @@ -1916,7 +1916,7 @@ void GeneratorProfile::setSechFunctionString(const std::string &sechFunctionStri mPimpl->mSechFunctionString = sechFunctionString; } -std::string GeneratorProfile::cschFunctionString() const +const std::string &GeneratorProfile::cschFunctionString() const { return mPimpl->mCschFunctionString; } @@ -1926,7 +1926,7 @@ void GeneratorProfile::setCschFunctionString(const std::string &cschFunctionStri mPimpl->mCschFunctionString = cschFunctionString; } -std::string GeneratorProfile::cothFunctionString() const +const std::string &GeneratorProfile::cothFunctionString() const { return mPimpl->mCothFunctionString; } @@ -1936,7 +1936,7 @@ void GeneratorProfile::setCothFunctionString(const std::string &cothFunctionStri mPimpl->mCothFunctionString = cothFunctionString; } -std::string GeneratorProfile::asecFunctionString() const +const std::string &GeneratorProfile::asecFunctionString() const { return mPimpl->mAsecFunctionString; } @@ -1946,7 +1946,7 @@ void GeneratorProfile::setAsecFunctionString(const std::string &asecFunctionStri mPimpl->mAsecFunctionString = asecFunctionString; } -std::string GeneratorProfile::acscFunctionString() const +const std::string &GeneratorProfile::acscFunctionString() const { return mPimpl->mAcscFunctionString; } @@ -1956,7 +1956,7 @@ void GeneratorProfile::setAcscFunctionString(const std::string &acscFunctionStri mPimpl->mAcscFunctionString = acscFunctionString; } -std::string GeneratorProfile::acotFunctionString() const +const std::string &GeneratorProfile::acotFunctionString() const { return mPimpl->mAcotFunctionString; } @@ -1966,7 +1966,7 @@ void GeneratorProfile::setAcotFunctionString(const std::string &acotFunctionStri mPimpl->mAcotFunctionString = acotFunctionString; } -std::string GeneratorProfile::asechFunctionString() const +const std::string &GeneratorProfile::asechFunctionString() const { return mPimpl->mAsechFunctionString; } @@ -1976,7 +1976,7 @@ void GeneratorProfile::setAsechFunctionString(const std::string &asechFunctionSt mPimpl->mAsechFunctionString = asechFunctionString; } -std::string GeneratorProfile::acschFunctionString() const +const std::string &GeneratorProfile::acschFunctionString() const { return mPimpl->mAcschFunctionString; } @@ -1986,7 +1986,7 @@ void GeneratorProfile::setAcschFunctionString(const std::string &acschFunctionSt mPimpl->mAcschFunctionString = acschFunctionString; } -std::string GeneratorProfile::acothFunctionString() const +const std::string &GeneratorProfile::acothFunctionString() const { return mPimpl->mAcothFunctionString; } @@ -1996,7 +1996,7 @@ void GeneratorProfile::setAcothFunctionString(const std::string &acothFunctionSt mPimpl->mAcothFunctionString = acothFunctionString; } -std::string GeneratorProfile::commentString() const +const std::string &GeneratorProfile::commentString() const { return mPimpl->mCommentString; } @@ -2006,7 +2006,7 @@ void GeneratorProfile::setCommentString(const std::string &commentString) mPimpl->mCommentString = commentString; } -std::string GeneratorProfile::originCommentString() const +const std::string &GeneratorProfile::originCommentString() const { return mPimpl->mOriginCommentString; } @@ -2016,7 +2016,7 @@ void GeneratorProfile::setOriginCommentString(const std::string &originCommentSt mPimpl->mOriginCommentString = originCommentString; } -std::string GeneratorProfile::interfaceFileNameString() const +const std::string &GeneratorProfile::interfaceFileNameString() const { return mPimpl->mInterfaceFileNameString; } @@ -2026,7 +2026,7 @@ void GeneratorProfile::setInterfaceFileNameString(const std::string &interfaceFi mPimpl->mInterfaceFileNameString = interfaceFileNameString; } -std::string GeneratorProfile::interfaceHeaderString() const +const std::string &GeneratorProfile::interfaceHeaderString() const { return mPimpl->mInterfaceHeaderString; } @@ -2036,7 +2036,7 @@ void GeneratorProfile::setInterfaceHeaderString(const std::string &interfaceHead mPimpl->mInterfaceHeaderString = interfaceHeaderString; } -std::string GeneratorProfile::implementationHeaderString() const +const std::string &GeneratorProfile::implementationHeaderString() const { return mPimpl->mImplementationHeaderString; } @@ -2046,7 +2046,7 @@ void GeneratorProfile::setImplementationHeaderString(const std::string &implemen mPimpl->mImplementationHeaderString = implementationHeaderString; } -std::string GeneratorProfile::interfaceVersionString() const +const std::string &GeneratorProfile::interfaceVersionString() const { return mPimpl->mInterfaceVersionString; } @@ -2056,7 +2056,7 @@ void GeneratorProfile::setInterfaceVersionString(const std::string &interfaceVer mPimpl->mInterfaceVersionString = interfaceVersionString; } -std::string GeneratorProfile::implementationVersionString() const +const std::string &GeneratorProfile::implementationVersionString() const { return mPimpl->mImplementationVersionString; } @@ -2066,7 +2066,7 @@ void GeneratorProfile::setImplementationVersionString(const std::string &impleme mPimpl->mImplementationVersionString = implementationVersionString; } -std::string GeneratorProfile::interfaceLibcellmlVersionString() const +const std::string &GeneratorProfile::interfaceLibcellmlVersionString() const { return mPimpl->mInterfaceLibcellmlVersionString; } @@ -2076,7 +2076,7 @@ void GeneratorProfile::setInterfaceLibcellmlVersionString(const std::string &int mPimpl->mInterfaceLibcellmlVersionString = interfaceLibcellmlVersionString; } -std::string GeneratorProfile::implementationLibcellmlVersionString() const +const std::string &GeneratorProfile::implementationLibcellmlVersionString() const { return mPimpl->mImplementationLibcellmlVersionString; } @@ -2086,7 +2086,7 @@ void GeneratorProfile::setImplementationLibcellmlVersionString(const std::string mPimpl->mImplementationLibcellmlVersionString = implementationLibcellmlVersionString; } -std::string GeneratorProfile::interfaceStateCountString() const +const std::string &GeneratorProfile::interfaceStateCountString() const { return mPimpl->mInterfaceStateCountString; } @@ -2096,7 +2096,7 @@ void GeneratorProfile::setInterfaceStateCountString(const std::string &interface mPimpl->mInterfaceStateCountString = interfaceStateCountString; } -std::string GeneratorProfile::implementationStateCountString() const +const std::string &GeneratorProfile::implementationStateCountString() const { return mPimpl->mImplementationStateCountString; } @@ -2106,7 +2106,7 @@ void GeneratorProfile::setImplementationStateCountString(const std::string &impl mPimpl->mImplementationStateCountString = implementationStateCountString; } -std::string GeneratorProfile::interfaceConstantCountString() const +const std::string &GeneratorProfile::interfaceConstantCountString() const { return mPimpl->mInterfaceConstantCountString; } @@ -2116,7 +2116,7 @@ void GeneratorProfile::setInterfaceConstantCountString(const std::string &interf mPimpl->mInterfaceConstantCountString = interfaceConstantCountString; } -std::string GeneratorProfile::implementationConstantCountString() const +const std::string &GeneratorProfile::implementationConstantCountString() const { return mPimpl->mImplementationConstantCountString; } @@ -2126,7 +2126,7 @@ void GeneratorProfile::setImplementationConstantCountString(const std::string &i mPimpl->mImplementationConstantCountString = implementationConstantCountString; } -std::string GeneratorProfile::interfaceComputedConstantCountString() const +const std::string &GeneratorProfile::interfaceComputedConstantCountString() const { return mPimpl->mInterfaceComputedConstantCountString; } @@ -2136,7 +2136,7 @@ void GeneratorProfile::setInterfaceComputedConstantCountString(const std::string mPimpl->mInterfaceComputedConstantCountString = interfaceComputedConstantCountString; } -std::string GeneratorProfile::implementationComputedConstantCountString() const +const std::string &GeneratorProfile::implementationComputedConstantCountString() const { return mPimpl->mImplementationComputedConstantCountString; } @@ -2146,7 +2146,7 @@ void GeneratorProfile::setImplementationComputedConstantCountString(const std::s mPimpl->mImplementationComputedConstantCountString = implementationComputedConstantCountString; } -std::string GeneratorProfile::interfaceAlgebraicVariableCountString() const +const std::string &GeneratorProfile::interfaceAlgebraicVariableCountString() const { return mPimpl->mInterfaceAlgebraicVariableCountString; } @@ -2156,7 +2156,7 @@ void GeneratorProfile::setInterfaceAlgebraicVariableCountString(const std::strin mPimpl->mInterfaceAlgebraicVariableCountString = interfaceAlgebraicVariableCountString; } -std::string GeneratorProfile::implementationAlgebraicVariableCountString() const +const std::string &GeneratorProfile::implementationAlgebraicVariableCountString() const { return mPimpl->mImplementationAlgebraicVariableCountString; } @@ -2166,7 +2166,7 @@ void GeneratorProfile::setImplementationAlgebraicVariableCountString(const std:: mPimpl->mImplementationAlgebraicVariableCountString = implementationAlgebraicVariableCountString; } -std::string GeneratorProfile::interfaceExternalVariableCountString() const +const std::string &GeneratorProfile::interfaceExternalVariableCountString() const { return mPimpl->mInterfaceExternalVariableCountString; } @@ -2176,7 +2176,7 @@ void GeneratorProfile::setInterfaceExternalVariableCountString(const std::string mPimpl->mInterfaceExternalVariableCountString = interfaceExternalVariableCountString; } -std::string GeneratorProfile::implementationExternalVariableCountString() const +const std::string &GeneratorProfile::implementationExternalVariableCountString() const { return mPimpl->mImplementationExternalVariableCountString; } @@ -2186,7 +2186,7 @@ void GeneratorProfile::setImplementationExternalVariableCountString(const std::s mPimpl->mImplementationExternalVariableCountString = implementationExternalVariableCountString; } -std::string GeneratorProfile::variableInfoObjectString() const +const std::string &GeneratorProfile::variableInfoObjectString() const { return mPimpl->mVariableInfoObjectString; } @@ -2196,7 +2196,7 @@ void GeneratorProfile::setVariableInfoObjectString(const std::string &variableIn mPimpl->mVariableInfoObjectString = variableInfoObjectString; } -std::string GeneratorProfile::interfaceVoiInfoString() const +const std::string &GeneratorProfile::interfaceVoiInfoString() const { return mPimpl->mInterfaceVoiInfoString; } @@ -2206,7 +2206,7 @@ void GeneratorProfile::setInterfaceVoiInfoString(const std::string &interfaceVoi mPimpl->mInterfaceVoiInfoString = interfaceVoiInfoString; } -std::string GeneratorProfile::implementationVoiInfoString() const +const std::string &GeneratorProfile::implementationVoiInfoString() const { return mPimpl->mImplementationVoiInfoString; } @@ -2216,7 +2216,7 @@ void GeneratorProfile::setImplementationVoiInfoString(const std::string &impleme mPimpl->mImplementationVoiInfoString = implementationVoiInfoString; } -std::string GeneratorProfile::interfaceStateInfoString() const +const std::string &GeneratorProfile::interfaceStateInfoString() const { return mPimpl->mInterfaceStateInfoString; } @@ -2226,7 +2226,7 @@ void GeneratorProfile::setInterfaceStateInfoString(const std::string &interfaceS mPimpl->mInterfaceStateInfoString = interfaceStateInfoString; } -std::string GeneratorProfile::implementationStateInfoString() const +const std::string &GeneratorProfile::implementationStateInfoString() const { return mPimpl->mImplementationStateInfoString; } @@ -2236,7 +2236,7 @@ void GeneratorProfile::setImplementationStateInfoString(const std::string &imple mPimpl->mImplementationStateInfoString = implementationStateInfoString; } -std::string GeneratorProfile::interfaceConstantInfoString() const +const std::string &GeneratorProfile::interfaceConstantInfoString() const { return mPimpl->mInterfaceConstantInfoString; } @@ -2246,7 +2246,7 @@ void GeneratorProfile::setInterfaceConstantInfoString(const std::string &interfa mPimpl->mInterfaceConstantInfoString = interfaceConstantInfoString; } -std::string GeneratorProfile::implementationConstantInfoString() const +const std::string &GeneratorProfile::implementationConstantInfoString() const { return mPimpl->mImplementationConstantInfoString; } @@ -2256,7 +2256,7 @@ void GeneratorProfile::setImplementationConstantInfoString(const std::string &im mPimpl->mImplementationConstantInfoString = implementationConstantInfoString; } -std::string GeneratorProfile::interfaceComputedConstantInfoString() const +const std::string &GeneratorProfile::interfaceComputedConstantInfoString() const { return mPimpl->mInterfaceComputedConstantInfoString; } @@ -2266,7 +2266,7 @@ void GeneratorProfile::setInterfaceComputedConstantInfoString(const std::string mPimpl->mInterfaceComputedConstantInfoString = interfaceComputedConstantInfoString; } -std::string GeneratorProfile::implementationComputedConstantInfoString() const +const std::string &GeneratorProfile::implementationComputedConstantInfoString() const { return mPimpl->mImplementationComputedConstantInfoString; } @@ -2276,7 +2276,7 @@ void GeneratorProfile::setImplementationComputedConstantInfoString(const std::st mPimpl->mImplementationComputedConstantInfoString = implementationComputedConstantInfoString; } -std::string GeneratorProfile::interfaceAlgebraicVariableInfoString() const +const std::string &GeneratorProfile::interfaceAlgebraicVariableInfoString() const { return mPimpl->mInterfaceAlgebraicVariableInfoString; } @@ -2286,7 +2286,7 @@ void GeneratorProfile::setInterfaceAlgebraicVariableInfoString(const std::string mPimpl->mInterfaceAlgebraicVariableInfoString = interfaceAlgebraicVariableInfoString; } -std::string GeneratorProfile::implementationAlgebraicVariableInfoString() const +const std::string &GeneratorProfile::implementationAlgebraicVariableInfoString() const { return mPimpl->mImplementationAlgebraicVariableInfoString; } @@ -2296,7 +2296,7 @@ void GeneratorProfile::setImplementationAlgebraicVariableInfoString(const std::s mPimpl->mImplementationAlgebraicVariableInfoString = implementationAlgebraicVariableInfoString; } -std::string GeneratorProfile::interfaceExternalVariableInfoString() const +const std::string &GeneratorProfile::interfaceExternalVariableInfoString() const { return mPimpl->mInterfaceExternalVariableInfoString; } @@ -2306,7 +2306,7 @@ void GeneratorProfile::setInterfaceExternalVariableInfoString(const std::string mPimpl->mInterfaceExternalVariableInfoString = interfaceExternalVariableInfoString; } -std::string GeneratorProfile::implementationExternalVariableInfoString() const +const std::string &GeneratorProfile::implementationExternalVariableInfoString() const { return mPimpl->mImplementationExternalVariableInfoString; } @@ -2316,7 +2316,7 @@ void GeneratorProfile::setImplementationExternalVariableInfoString(const std::st mPimpl->mImplementationExternalVariableInfoString = implementationExternalVariableInfoString; } -std::string GeneratorProfile::variableInfoEntryString() const +const std::string &GeneratorProfile::variableInfoEntryString() const { return mPimpl->mVariableInfoEntryString; } @@ -2326,7 +2326,7 @@ void GeneratorProfile::setVariableInfoEntryString(const std::string &variableInf mPimpl->mVariableInfoEntryString = variableInfoEntryString; } -std::string GeneratorProfile::voiString() const +const std::string &GeneratorProfile::voiString() const { return mPimpl->mVoiString; } @@ -2336,7 +2336,7 @@ void GeneratorProfile::setVoiString(const std::string &voiString) mPimpl->mVoiString = voiString; } -std::string GeneratorProfile::statesArrayString() const +const std::string &GeneratorProfile::statesArrayString() const { return mPimpl->mStatesArrayString; } @@ -2346,7 +2346,7 @@ void GeneratorProfile::setStatesArrayString(const std::string &statesArrayString mPimpl->mStatesArrayString = statesArrayString; } -std::string GeneratorProfile::ratesArrayString() const +const std::string &GeneratorProfile::ratesArrayString() const { return mPimpl->mRatesArrayString; } @@ -2356,7 +2356,7 @@ void GeneratorProfile::setRatesArrayString(const std::string &ratesArrayString) mPimpl->mRatesArrayString = ratesArrayString; } -std::string GeneratorProfile::constantsArrayString() const +const std::string &GeneratorProfile::constantsArrayString() const { return mPimpl->mConstantsArrayString; } @@ -2366,7 +2366,7 @@ void GeneratorProfile::setConstantsArrayString(const std::string &constantsArray mPimpl->mConstantsArrayString = constantsArrayString; } -std::string GeneratorProfile::computedConstantsArrayString() const +const std::string &GeneratorProfile::computedConstantsArrayString() const { return mPimpl->mComputedConstantsArrayString; } @@ -2376,7 +2376,7 @@ void GeneratorProfile::setComputedConstantsArrayString(const std::string &comput mPimpl->mComputedConstantsArrayString = computedConstantsArrayString; } -std::string GeneratorProfile::algebraicVariablesArrayString() const +const std::string &GeneratorProfile::algebraicVariablesArrayString() const { return mPimpl->mAlgebraicVariablesArrayString; } @@ -2386,7 +2386,7 @@ void GeneratorProfile::setAlgebraicVariablesArrayString(const std::string &algeb mPimpl->mAlgebraicVariablesArrayString = algebraicVariablesArrayString; } -std::string GeneratorProfile::externalVariablesArrayString() const +const std::string &GeneratorProfile::externalVariablesArrayString() const { return mPimpl->mExternalVariablesArrayString; } @@ -2396,7 +2396,7 @@ void GeneratorProfile::setExternalVariablesArrayString(const std::string &extern mPimpl->mExternalVariablesArrayString = externalVariablesArrayString; } -std::string GeneratorProfile::externalVariableMethodTypeDefinitionString(bool forDifferentialModel) const +const std::string &GeneratorProfile::externalVariableMethodTypeDefinitionString(bool forDifferentialModel) const { if (forDifferentialModel) { return mPimpl->mExternalVariableMethodTypeDefinitionDiffString; @@ -2415,7 +2415,7 @@ void GeneratorProfile::setExternalVariableMethodTypeDefinitionString(bool forDif } } -std::string GeneratorProfile::externalVariableMethodCallString(bool forDifferentialModel) const +const std::string &GeneratorProfile::externalVariableMethodCallString(bool forDifferentialModel) const { if (forDifferentialModel) { return mPimpl->mExternalVariableMethodCallDiffString; @@ -2434,8 +2434,8 @@ void GeneratorProfile::setExternalVariableMethodCallString(bool forDifferentialM } } -std::string GeneratorProfile::rootFindingInfoObjectString(bool forDifferentialModel, - bool withExternalVariables) const +const std::string &GeneratorProfile::rootFindingInfoObjectString(bool forDifferentialModel, + bool withExternalVariables) const { if (forDifferentialModel) { if (withExternalVariables) { @@ -2471,7 +2471,7 @@ void GeneratorProfile::setRootFindingInfoObjectString(bool forDifferentialModel, } } -std::string GeneratorProfile::externNlaSolveMethodString() const +const std::string &GeneratorProfile::externNlaSolveMethodString() const { return mPimpl->mExternNlaSolveMethodString; } @@ -2481,8 +2481,8 @@ void GeneratorProfile::setExternNlaSolveMethodString(const std::string &externNl mPimpl->mExternNlaSolveMethodString = externNlaSolveMethodString; } -std::string GeneratorProfile::findRootCallString(bool forDifferentialModel, - bool withExternalVariables) const +const std::string &GeneratorProfile::findRootCallString(bool forDifferentialModel, + bool withExternalVariables) const { if (forDifferentialModel) { if (withExternalVariables) { @@ -2518,8 +2518,8 @@ void GeneratorProfile::setFindRootCallString(bool forDifferentialModel, } } -std::string GeneratorProfile::findRootMethodString(bool forDifferentialModel, - bool withExternalVariables) const +const std::string &GeneratorProfile::findRootMethodString(bool forDifferentialModel, + bool withExternalVariables) const { if (forDifferentialModel) { if (withExternalVariables) { @@ -2555,8 +2555,8 @@ void GeneratorProfile::setFindRootMethodString(bool forDifferentialModel, } } -std::string GeneratorProfile::nlaSolveCallString(bool forDifferentialModel, - bool withExternalVariables) const +const std::string &GeneratorProfile::nlaSolveCallString(bool forDifferentialModel, + bool withExternalVariables) const { if (forDifferentialModel) { if (withExternalVariables) { @@ -2592,8 +2592,8 @@ void GeneratorProfile::setNlaSolveCallString(bool forDifferentialModel, } } -std::string GeneratorProfile::objectiveFunctionMethodString(bool forDifferentialModel, - bool withExternalVariables) const +const std::string &GeneratorProfile::objectiveFunctionMethodString(bool forDifferentialModel, + bool withExternalVariables) const { if (forDifferentialModel) { if (withExternalVariables) { @@ -2629,7 +2629,7 @@ void GeneratorProfile::setObjectiveFunctionMethodString(bool forDifferentialMode } } -std::string GeneratorProfile::uArrayString() const +const std::string &GeneratorProfile::uArrayString() const { return mPimpl->mUArrayString; } @@ -2639,7 +2639,7 @@ void GeneratorProfile::setUArrayString(const std::string &uArrayString) mPimpl->mUArrayString = uArrayString; } -std::string GeneratorProfile::fArrayString() const +const std::string &GeneratorProfile::fArrayString() const { return mPimpl->mFArrayString; } @@ -2649,7 +2649,7 @@ void GeneratorProfile::setFArrayString(const std::string &fArrayString) mPimpl->mFArrayString = fArrayString; } -std::string GeneratorProfile::interfaceCreateStatesArrayMethodString() const +const std::string &GeneratorProfile::interfaceCreateStatesArrayMethodString() const { return mPimpl->mInterfaceCreateStatesArrayMethodString; } @@ -2659,7 +2659,7 @@ void GeneratorProfile::setInterfaceCreateStatesArrayMethodString(const std::stri mPimpl->mInterfaceCreateStatesArrayMethodString = interfaceCreateStatesArrayMethodString; } -std::string GeneratorProfile::implementationCreateStatesArrayMethodString() const +const std::string &GeneratorProfile::implementationCreateStatesArrayMethodString() const { return mPimpl->mImplementationCreateStatesArrayMethodString; } @@ -2669,7 +2669,7 @@ void GeneratorProfile::setImplementationCreateStatesArrayMethodString(const std: mPimpl->mImplementationCreateStatesArrayMethodString = implementationCreateStatesArrayMethodString; } -std::string GeneratorProfile::interfaceCreateConstantsArrayMethodString() const +const std::string &GeneratorProfile::interfaceCreateConstantsArrayMethodString() const { return mPimpl->mInterfaceCreateConstantsArrayMethodString; } @@ -2679,7 +2679,7 @@ void GeneratorProfile::setInterfaceCreateConstantsArrayMethodString(const std::s mPimpl->mInterfaceCreateConstantsArrayMethodString = interfaceCreateConstantsArrayMethodString; } -std::string GeneratorProfile::implementationCreateConstantsArrayMethodString() const +const std::string &GeneratorProfile::implementationCreateConstantsArrayMethodString() const { return mPimpl->mImplementationCreateConstantsArrayMethodString; } @@ -2689,7 +2689,7 @@ void GeneratorProfile::setImplementationCreateConstantsArrayMethodString(const s mPimpl->mImplementationCreateConstantsArrayMethodString = implementationCreateConstantsArrayMethodString; } -std::string GeneratorProfile::interfaceCreateComputedConstantsArrayMethodString() const +const std::string &GeneratorProfile::interfaceCreateComputedConstantsArrayMethodString() const { return mPimpl->mInterfaceCreateComputedConstantsArrayMethodString; } @@ -2699,7 +2699,7 @@ void GeneratorProfile::setInterfaceCreateComputedConstantsArrayMethodString(cons mPimpl->mInterfaceCreateComputedConstantsArrayMethodString = interfaceCreateComputedConstantsArrayMethodString; } -std::string GeneratorProfile::implementationCreateComputedConstantsArrayMethodString() const +const std::string &GeneratorProfile::implementationCreateComputedConstantsArrayMethodString() const { return mPimpl->mImplementationCreateComputedConstantsArrayMethodString; } @@ -2709,7 +2709,7 @@ void GeneratorProfile::setImplementationCreateComputedConstantsArrayMethodString mPimpl->mImplementationCreateComputedConstantsArrayMethodString = implementationCreateComputedConstantsArrayMethodString; } -std::string GeneratorProfile::interfaceCreateAlgebraicVariablesArrayMethodString() const +const std::string &GeneratorProfile::interfaceCreateAlgebraicVariablesArrayMethodString() const { return mPimpl->mInterfaceCreateAlgebraicVariablesArrayMethodString; } @@ -2719,7 +2719,7 @@ void GeneratorProfile::setInterfaceCreateAlgebraicVariablesArrayMethodString(con mPimpl->mInterfaceCreateAlgebraicVariablesArrayMethodString = interfaceCreateAlgebraicVariablesArrayMethodString; } -std::string GeneratorProfile::implementationCreateAlgebraicVariablesArrayMethodString() const +const std::string &GeneratorProfile::implementationCreateAlgebraicVariablesArrayMethodString() const { return mPimpl->mImplementationCreateAlgebraicVariablesArrayMethodString; } @@ -2729,7 +2729,7 @@ void GeneratorProfile::setImplementationCreateAlgebraicVariablesArrayMethodStrin mPimpl->mImplementationCreateAlgebraicVariablesArrayMethodString = implementationCreateAlgebraicVariablesArrayMethodString; } -std::string GeneratorProfile::interfaceCreateExternalVariablesArrayMethodString() const +const std::string &GeneratorProfile::interfaceCreateExternalVariablesArrayMethodString() const { return mPimpl->mInterfaceCreateExternalVariablesArrayMethodString; } @@ -2739,7 +2739,7 @@ void GeneratorProfile::setInterfaceCreateExternalVariablesArrayMethodString(cons mPimpl->mInterfaceCreateExternalVariablesArrayMethodString = interfaceCreateExternalVariablesArrayMethodString; } -std::string GeneratorProfile::implementationCreateExternalVariablesArrayMethodString() const +const std::string &GeneratorProfile::implementationCreateExternalVariablesArrayMethodString() const { return mPimpl->mImplementationCreateExternalVariablesArrayMethodString; } @@ -2749,7 +2749,7 @@ void GeneratorProfile::setImplementationCreateExternalVariablesArrayMethodString mPimpl->mImplementationCreateExternalVariablesArrayMethodString = implementationCreateExternalVariablesArrayMethodString; } -std::string GeneratorProfile::interfaceDeleteArrayMethodString() const +const std::string &GeneratorProfile::interfaceDeleteArrayMethodString() const { return mPimpl->mInterfaceDeleteArrayMethodString; } @@ -2759,7 +2759,7 @@ void GeneratorProfile::setInterfaceDeleteArrayMethodString(const std::string &in mPimpl->mInterfaceDeleteArrayMethodString = interfaceDeleteArrayMethodString; } -std::string GeneratorProfile::implementationDeleteArrayMethodString() const +const std::string &GeneratorProfile::implementationDeleteArrayMethodString() const { return mPimpl->mImplementationDeleteArrayMethodString; } @@ -2769,7 +2769,7 @@ void GeneratorProfile::setImplementationDeleteArrayMethodString(const std::strin mPimpl->mImplementationDeleteArrayMethodString = implementationDeleteArrayMethodString; } -std::string GeneratorProfile::interfaceInitialiseArraysMethodString(bool forDifferentialModel) const +const std::string &GeneratorProfile::interfaceInitialiseArraysMethodString(bool forDifferentialModel) const { if (forDifferentialModel) { return mPimpl->mInterfaceInitialiseArraysMethodDiffString; @@ -2788,7 +2788,7 @@ void GeneratorProfile::setInterfaceInitialiseArraysMethodString(bool forDifferen } } -std::string GeneratorProfile::implementationInitialiseArraysMethodString(bool forDifferentialModel) const +const std::string &GeneratorProfile::implementationInitialiseArraysMethodString(bool forDifferentialModel) const { if (forDifferentialModel) { return mPimpl->mImplementationInitialiseArraysMethodDiffString; @@ -2807,7 +2807,7 @@ void GeneratorProfile::setImplementationInitialiseArraysMethodString(bool forDif } } -std::string GeneratorProfile::interfaceComputeComputedConstantsMethodString(bool forDifferentialModel) const +const std::string &GeneratorProfile::interfaceComputeComputedConstantsMethodString(bool forDifferentialModel) const { if (forDifferentialModel) { return mPimpl->mInterfaceComputeComputedConstantsMethodDiffString; @@ -2826,7 +2826,7 @@ void GeneratorProfile::setInterfaceComputeComputedConstantsMethodString(bool for } } -std::string GeneratorProfile::implementationComputeComputedConstantsMethodString(bool forDifferentialModel) const +const std::string &GeneratorProfile::implementationComputeComputedConstantsMethodString(bool forDifferentialModel) const { if (forDifferentialModel) { return mPimpl->mImplementationComputeComputedConstantsMethodDiffString; @@ -2845,7 +2845,7 @@ void GeneratorProfile::setImplementationComputeComputedConstantsMethodString(boo } } -std::string GeneratorProfile::interfaceComputeRatesMethodString(bool withExternalVariables) const +const std::string &GeneratorProfile::interfaceComputeRatesMethodString(bool withExternalVariables) const { if (withExternalVariables) { return mPimpl->mInterfaceComputeRatesMethodWevString; @@ -2864,7 +2864,7 @@ void GeneratorProfile::setInterfaceComputeRatesMethodString(bool withExternalVar } } -std::string GeneratorProfile::implementationComputeRatesMethodString(bool withExternalVariables) const +const std::string &GeneratorProfile::implementationComputeRatesMethodString(bool withExternalVariables) const { if (withExternalVariables) { return mPimpl->mImplementationComputeRatesMethodWevString; @@ -2883,8 +2883,8 @@ void GeneratorProfile::setImplementationComputeRatesMethodString(bool withExtern } } -std::string GeneratorProfile::interfaceComputeVariablesMethodString(bool forDifferentialModel, - bool withExternalVariables) const +const std::string &GeneratorProfile::interfaceComputeVariablesMethodString(bool forDifferentialModel, + bool withExternalVariables) const { if (forDifferentialModel) { if (withExternalVariables) { @@ -2920,8 +2920,8 @@ void GeneratorProfile::setInterfaceComputeVariablesMethodString(bool forDifferen } } -std::string GeneratorProfile::implementationComputeVariablesMethodString(bool forDifferentialModel, - bool withExternalVariables) const +const std::string &GeneratorProfile::implementationComputeVariablesMethodString(bool forDifferentialModel, + bool withExternalVariables) const { if (forDifferentialModel) { if (withExternalVariables) { @@ -2957,7 +2957,7 @@ void GeneratorProfile::setImplementationComputeVariablesMethodString(bool forDif } } -std::string GeneratorProfile::emptyMethodString() const +const std::string &GeneratorProfile::emptyMethodString() const { return mPimpl->mEmptyMethodString; } @@ -2967,7 +2967,7 @@ void GeneratorProfile::setEmptyMethodString(const std::string &emptyMethodString mPimpl->mEmptyMethodString = emptyMethodString; } -std::string GeneratorProfile::indentString() const +const std::string &GeneratorProfile::indentString() const { return mPimpl->mIndentString; } @@ -2977,7 +2977,7 @@ void GeneratorProfile::setIndentString(const std::string &indentString) mPimpl->mIndentString = indentString; } -std::string GeneratorProfile::variableDeclarationString() const +const std::string &GeneratorProfile::variableDeclarationString() const { return mPimpl->mVariableDeclarationString; } @@ -2987,7 +2987,7 @@ void GeneratorProfile::setVariableDeclarationString(const std::string &variableD mPimpl->mVariableDeclarationString = variableDeclarationString; } -std::string GeneratorProfile::openArrayString() const +const std::string &GeneratorProfile::openArrayString() const { return mPimpl->mOpenArrayString; } @@ -2997,7 +2997,7 @@ void GeneratorProfile::setOpenArrayString(const std::string &openArrayString) mPimpl->mOpenArrayString = openArrayString; } -std::string GeneratorProfile::closeArrayString() const +const std::string &GeneratorProfile::closeArrayString() const { return mPimpl->mCloseArrayString; } @@ -3007,7 +3007,7 @@ void GeneratorProfile::setCloseArrayString(const std::string &closeArrayString) mPimpl->mCloseArrayString = closeArrayString; } -std::string GeneratorProfile::arrayElementSeparatorString() const +const std::string &GeneratorProfile::arrayElementSeparatorString() const { return mPimpl->mArrayElementSeparatorString; } @@ -3017,7 +3017,7 @@ void GeneratorProfile::setArrayElementSeparatorString(const std::string &arrayEl mPimpl->mArrayElementSeparatorString = arrayElementSeparatorString; } -std::string GeneratorProfile::commandSeparatorString() const +const std::string &GeneratorProfile::commandSeparatorString() const { return mPimpl->mCommandSeparatorString; } diff --git a/src/generatorprofiletools.cpp b/src/generatorprofiletools.cpp index bc9fe8615..b275bae57 100644 --- a/src/generatorprofiletools.cpp +++ b/src/generatorprofiletools.cpp @@ -274,6 +274,8 @@ std::string generatorProfileAsString(const GeneratorProfilePtr &generatorProfile TRUE_VALUE : FALSE_VALUE; + profileContents.reserve(4096); + // Equality. profileContents += generatorProfile->equalityString(); diff --git a/src/generatorvariabletracker.cpp b/src/generatorvariabletracker.cpp index 7ab4f5263..856a9d8bc 100644 --- a/src/generatorvariabletracker.cpp +++ b/src/generatorvariabletracker.cpp @@ -299,10 +299,14 @@ void GeneratorVariableTracker::GeneratorVariableTrackerImpl::trackAllAlgebraicVa std::vector GeneratorVariableTracker::GeneratorVariableTrackerImpl::trackableVariables(const AnalyserModelPtr &analyserModel) const { - auto res = analyserModel->constants(); - auto computedConstants = analyserModel->computedConstants(); - auto algebraic = analyserModel->algebraicVariables(); + const auto &constants = analyserModel->constants(); + const auto &computedConstants = analyserModel->computedConstants(); + const auto &algebraic = analyserModel->algebraicVariables(); + std::vector res; + + res.reserve(constants.size() + computedConstants.size() + algebraic.size()); + res.insert(res.end(), constants.begin(), constants.end()); res.insert(res.end(), computedConstants.begin(), computedConstants.end()); res.insert(res.end(), algebraic.begin(), algebraic.end()); diff --git a/src/importedentity.cpp b/src/importedentity.cpp index 4d859929e..4a93560d2 100644 --- a/src/importedentity.cpp +++ b/src/importedentity.cpp @@ -56,7 +56,7 @@ void ImportedEntity::setImportSource(const ImportSourcePtr &importSource) mPimpl->mImportSource = importSource; } -std::string ImportedEntity::importReference() const +const std::string &ImportedEntity::importReference() const { return mPimpl->mImportReference; } diff --git a/src/importer.cpp b/src/importer.cpp index b0e336b28..429216958 100644 --- a/src/importer.cpp +++ b/src/importer.cpp @@ -20,6 +20,7 @@ limitations under the License. #include #include #include +#include #include "libcellml/importsource.h" #include "libcellml/model.h" @@ -116,7 +117,7 @@ Importer::~Importer() std::vector::const_iterator Importer::ImporterImpl::findImportSource(const ImportSourcePtr &importSource) const { return std::find_if(mImports.begin(), mImports.end(), - [=](const ImportSourcePtr &importSrc) -> bool { return importSource->equals(importSrc); }); + [&](const ImportSourcePtr &importSrc) -> bool { return importSource->equals(importSrc); }); } std::string Importer::ImporterImpl::modelUrl(const ModelPtr &model) const @@ -332,12 +333,13 @@ std::string resolvePath(const std::string &filename, const std::string &base) bool Importer::ImporterImpl::fetchModel(const ImportSourcePtr &importSource, const std::string &baseFile) { std::string url = normaliseDirectorySeparator(importSource->url()); - if (mLibrary.count(url) == 0) { + if (mLibrary.find(url) == mLibrary.end()) { url = resolvePath(url, baseFile); } ModelPtr model; - if (mLibrary.count(url) == 0) { + auto libraryIt = mLibrary.find(url); + if (libraryIt == mLibrary.end()) { // If the URL has not ever been resolved into a model in this library, with or // without baseFile, parse it and save. std::ifstream file(url); @@ -378,7 +380,7 @@ bool Importer::ImporterImpl::fetchModel(const ImportSourcePtr &importSource, con } mLibrary.insert(std::make_pair(url, model)); } else { - model = mLibrary[url]; + model = libraryIt->second; } importSource->setModel(model); return true; @@ -815,7 +817,8 @@ ComponentPtr flattenComponent(const ComponentEntityPtr &parent, ComponentPtr &co // Clone import model to not affect origin import model units. auto clonedImportModel = importModel->clone(); - NameList compNames = componentNames(model); + NameList compNamesList = componentNames(model); + std::unordered_set compNames(compNamesList.begin(), compNamesList.end()); // Determine the stack for the destination component. IndexStack destinationComponentBaseIndexStack = indexStackOf(component); @@ -845,7 +848,7 @@ ComponentPtr flattenComponent(const ComponentEntityPtr &parent, ComponentPtr &co StringStringMap aliasedUnitsNames; for (const auto &units : requiredUnits) { const auto iterator = std::find_if(uniqueRequiredUnits.begin(), uniqueRequiredUnits.end(), - [=](const UnitsPtr &u) -> bool { return Units::equivalent(u, units); }); + [&](const UnitsPtr &u) -> bool { return Units::equivalent(u, units); }); if (iterator == uniqueRequiredUnits.end()) { uniqueRequiredUnits.push_back(units); } else if ((*iterator)->name() != units->name()) { @@ -866,7 +869,7 @@ ComponentPtr flattenComponent(const ComponentEntityPtr &parent, ComponentPtr &co std::string originalName = entry.first; size_t count = 0; std::string newName = originalName; - while (std::find(compNames.begin(), compNames.end(), newName) != compNames.end()) { + while (compNames.count(newName) != 0) { newName = originalName + "_" + convertToString(++count); } if (originalName != newName) { @@ -1003,8 +1006,9 @@ size_t Importer::libraryCount() ModelPtr Importer::library(const std::string &key) { auto normalisedKey = normaliseDirectorySeparator(key); - if (pFunc()->mLibrary.count(normalisedKey) != 0) { - return pFunc()->mLibrary[normalisedKey]; + auto it = pFunc()->mLibrary.find(normalisedKey); + if (it != pFunc()->mLibrary.end()) { + return it->second; } return nullptr; } @@ -1026,22 +1030,18 @@ ModelPtr Importer::library(const size_t &index) bool Importer::addModel(const ModelPtr &model, const std::string &key) { auto normalisedKey = normaliseDirectorySeparator(key); - if (pFunc()->mLibrary.count(normalisedKey) != 0) { - // If the key already exists in the library, do nothing. - return false; - } - pFunc()->mLibrary.insert(std::make_pair(normalisedKey, model)); - return true; + return pFunc()->mLibrary.emplace(normalisedKey, model).second; } bool Importer::replaceModel(const ModelPtr &model, const std::string &key) { auto normalisedKey = normaliseDirectorySeparator(key); - if (pFunc()->mLibrary.count(normalisedKey) == 0) { + auto it = pFunc()->mLibrary.find(normalisedKey); + if (it == pFunc()->mLibrary.end()) { // If the key is not found, do nothing. return false; } - pFunc()->mLibrary[normalisedKey] = model; + it->second = model; return true; } @@ -1077,7 +1077,7 @@ bool Importer::addImportSource(const ImportSourcePtr &importSource) // Prevent adding the same import source. if (std::find_if(pFunc()->mImports.begin(), pFunc()->mImports.end(), - [=](const ImportSourcePtr &importSrc) -> bool { return importSource == importSrc; }) + [&](const ImportSourcePtr &importSrc) -> bool { return importSource == importSrc; }) != pFunc()->mImports.end()) { return false; } diff --git a/src/importsource.cpp b/src/importsource.cpp index 4d929fd00..eec70a689 100644 --- a/src/importsource.cpp +++ b/src/importsource.cpp @@ -62,7 +62,7 @@ ImportSourcePtr ImportSource::create() noexcept return std::shared_ptr {new ImportSource {}}; } -std::string ImportSource::url() const +const std::string &ImportSource::url() const { return pFunc()->mUrl; } diff --git a/src/internaltypes.h b/src/internaltypes.h index e21e35ed6..f7304ba05 100644 --- a/src/internaltypes.h +++ b/src/internaltypes.h @@ -18,6 +18,7 @@ limitations under the License. #include #include +#include #include #include @@ -29,7 +30,7 @@ namespace libcellml { const std::string ORIGIN_MODEL_REF = ":this:"; -using ComponentNameMap = std::map; /**< Type definition for map of component name to component pointer. */ +using ComponentNameMap = std::unordered_map; /**< Type definition for map of component name to component pointer. */ using IndexStack = std::vector; /**< Type definition for tracking indices. */ using EquivalenceMap = std::map>; /**< Type definition for map of variable equivalences defined over model. */ @@ -37,7 +38,7 @@ using EquivalenceMap = std::map>; /**< Type using NamePair = std::pair; /**< Type definition for pair of names. */ using NameList = std::vector; /**< Type definition for list of names. */ using DescriptionList = std::vector>; /**< Type definition for list of variables and associated description. */ -using StringStringMap = std::map; /**< Type definition for map of string to string. */ +using StringStringMap = std::unordered_map; /**< Type definition for map of string to string. */ using UniqueNames = std::set; /**< Type definition for a set of unique names. */ using NodeAttributeNamespaceInfo = std::vector>; /**< Type definition for attribute namespace information. */ @@ -56,7 +57,7 @@ using IdMap = std::map>>; / using ImportLibrary = std::map; /** Type definition for library map of imported models. */ using IdList = std::unordered_set; /**< Type definition for list of identifiers. */ -using ResetOrderMap = std::map>; /** Type definition for map of variable to reset order. **/ +using ResetOrderMap = std::unordered_map>; /** Type definition for map of variable to reset order. **/ using AnalyserEquationAstWeakPtr = std::weak_ptr; /**< Type definition for weak analyser equation AST pointer. */ using AnalyserEquationWeakPtr = std::weak_ptr; /**< Type definition for weak analyser equation pointer. */ @@ -76,7 +77,7 @@ using ModelConstPtr = std::shared_ptr; /**< Type definition for sha using ParentedEntityConstPtr = std::shared_ptr; /**< Type definition for shared parented entity const pointer. */ using UnitsConstPtr = std::shared_ptr; /**< Type definition for shared units const pointer. */ -using ConnectionMap = std::map; /**< Type definition for a connection map.*/ +using ConnectionMap = std::unordered_map; /**< Type definition for a connection map.*/ using NamePairList = std::vector; /**< Type definition for a list of a pair of names. */ /** diff --git a/src/issue.cpp b/src/issue.cpp index da64bd978..f0d8eb776 100644 --- a/src/issue.cpp +++ b/src/issue.cpp @@ -51,7 +51,7 @@ Issue::~Issue() delete mPimpl; } -std::string Issue::description() const +const std::string &Issue::description() const { return mPimpl->mDescription; } diff --git a/src/model.cpp b/src/model.cpp index 56e18d6ad..3ff83def3 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -18,6 +18,7 @@ limitations under the License. #include #include +#include #include #include "libcellml/component.h" @@ -37,7 +38,7 @@ namespace libcellml { std::vector::const_iterator Model::ModelImpl::findUnits(const std::string &name) const { return std::find_if(mUnits.begin(), mUnits.end(), - [=](const UnitsPtr &u) -> bool { return u->name() == name; }); + [&](const UnitsPtr &u) -> bool { return u->name() == name; }); } std::vector::const_iterator Model::ModelImpl::findUnits(const UnitsPtr &units) const @@ -47,7 +48,7 @@ std::vector::const_iterator Model::ModelImpl::findUnits(const UnitsPtr return result; } return std::find_if(mUnits.begin(), mUnits.end(), - [=](const UnitsPtr &u) -> bool { return u->equals(units); }); + [&](const UnitsPtr &u) -> bool { return u->equals(units); }); } bool Model::ModelImpl::equalUnits(const ModelPtr &other) const @@ -461,19 +462,20 @@ bool Model::doEquals(const EntityPtr &other) const std::vector Model::importRequirements() const { std::vector requirements; + std::unordered_set seen; auto importedComponents = getImportedComponents(shared_from_this()); auto importedUnits = getImportedUnits(shared_from_this()); for (auto &component : importedComponents) { auto url = component->importSource()->url(); - if (std::find(requirements.begin(), requirements.end(), url) == requirements.end()) { + if (seen.insert(url).second) { requirements.push_back(url); } } for (auto &units : importedUnits) { auto url = units->importSource()->url(); - if (std::find(requirements.begin(), requirements.end(), url) == requirements.end()) { + if (seen.insert(url).second) { requirements.push_back(url); } } diff --git a/src/namedentity.cpp b/src/namedentity.cpp index 835448808..6a245a07a 100644 --- a/src/namedentity.cpp +++ b/src/namedentity.cpp @@ -40,7 +40,7 @@ void NamedEntity::setName(const std::string &name) pFunc()->mName = name; } -std::string NamedEntity::name() const +const std::string &NamedEntity::name() const { return pFunc()->mName; } diff --git a/src/parser.cpp b/src/parser.cpp index c24d51a00..59f3c3f25 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -407,8 +407,8 @@ void Parser::ParserImpl::loadModel(const ModelPtr &model, const std::string &inp auto elementNamespaceMap = traverseTreeForElementNamespaces(node); if (mParsing20Version) { for (const auto &e : elementNamespaceMap) { - std::string name = e.first; - std::string uri = e.second; + const auto &name = e.first; + const auto &uri = e.second; if ((uri != CELLML_2_0_NS) && (uri != MATHML_NS)) { auto issue = Issue::IssueImpl::create(); issue->mPimpl->setDescription("Element '" + name + "' uses namespace '" + uri + "' which does not belong to an allowed namespace. "); @@ -421,10 +421,10 @@ void Parser::ParserImpl::loadModel(const ModelPtr &model, const std::string &inp auto attributeNamespaceMap = traverseTreeForAttributeNamespaces(node); if (mParsing20Version) { for (const auto &e : attributeNamespaceMap) { - std::string nodeName = std::get<0>(e); - std::string nodeUri = std::get<4>(e); - std::string attributeName = std::get<1>(e); - std::string uri = std::get<3>(e); + const auto &nodeName = std::get<0>(e); + const auto &nodeUri = std::get<4>(e); + const auto &attributeName = std::get<1>(e); + const auto &uri = std::get<3>(e); if ((nodeName == "cn") && (nodeUri == MATHML_NS) && (attributeName == "units") && (uri == CELLML_2_0_NS)) { // Explicitly allowed attribute namespace prefix. } else if ((nodeName == "import") && (nodeUri == CELLML_2_0_NS) && (attributeName == "href") && (uri == XLINK_NS)) { @@ -982,6 +982,7 @@ void Parser::ParserImpl::loadVariable(const VariablePtr &variable, const XmlNode if (!nameAttributePresent || !unitsAttributePresent) { auto issue = Issue::IssueImpl::create(); std::string description = "Variable "; + description.reserve(256); if (nameAttributePresent) { description += "'" + node->attribute("name") + "' does not specify a units attribute."; } else if (unitsAttributePresent) { diff --git a/src/printer.cpp b/src/printer.cpp index 6a39d3a5f..7cda04068 100644 --- a/src/printer.cpp +++ b/src/printer.cpp @@ -16,7 +16,9 @@ limitations under the License. #include "libcellml/printer.h" -#include +#include +#include +#include #include #include @@ -57,8 +59,12 @@ class Printer::PrinterImpl: public Logger::LoggerImpl std::string printMapVariables(const VariablePairPtr &variablePair, IdList &idList, bool autoIds) { - std::string mapVariables = "variable1()->name() + "\"" - + " variable_2=\"" + variablePair->variable2()->name() + "\""; + const auto &variable1Name = variablePair->variable1()->name(); + const auto &variable2Name = variablePair->variable2()->name(); + std::string mapVariables; + mapVariables.reserve(variable1Name.size() + variable2Name.size() + 64); + mapVariables = "variable1(), variablePair->variable2()); if (!mappingId.empty()) { mapVariables += " id=\"" + mappingId + "\""; @@ -72,22 +78,16 @@ std::string printMapVariables(const VariablePairPtr &variablePair, IdList &idLis std::string printConnections(const ComponentMap &componentMap, const VariableMap &variableMap, IdList &idList, bool autoIds) { std::string connections; - ComponentMap serialisedComponentMap; + connections.reserve(128 * componentMap.size()); + using ComponentPairKey = std::pair; + std::set serialisedComponentPairs; size_t componentMapIndex1 = 0; for (auto iterPair = componentMap.begin(); iterPair < componentMap.end(); ++iterPair) { ComponentPtr currentComponent1 = iterPair->first; ComponentPtr currentComponent2 = iterPair->second; - ComponentPair currentComponentPair = std::make_pair(currentComponent1, currentComponent2); - // Check whether this set of connections has already been serialised. - bool pairFound = false; - for (const auto &serialisedIterPair : serialisedComponentMap) { - if (serialisedIterPair == currentComponentPair) { - pairFound = true; - break; - } - } + ComponentPairKey currentKey = std::make_pair(currentComponent1.get(), currentComponent2.get()); // Continue to the next component pair if the current pair has already been serialised. - if (pairFound) { + if (!serialisedComponentPairs.insert(currentKey).second) { ++componentMapIndex1; continue; } @@ -118,7 +118,6 @@ std::string printConnections(const ComponentMap &componentMap, const VariableMap connections += " id=\"" + makeUniqueId(idList) + "\""; } connections += ">" + mappingVariables + ""; - serialisedComponentMap.push_back(currentComponentPair); ++componentMapIndex1; } @@ -128,14 +127,20 @@ std::string printConnections(const ComponentMap &componentMap, const VariableMap std::string Printer::PrinterImpl::printMath(const std::string &math) { static const std::string wrapElementName = "math_wrap_as_single_root_element"; - static const std::regex before(">[\\s\n\t]*"); - static const std::regex after("[\\s\n\t]*<"); - static const std::regex xmlDeclaration(R"|(<\?xml[[:space:]]+version=.*\?>)|"); XmlDocPtr xmlDoc = std::make_shared(); xmlKeepBlanksDefault(0); // Remove any XML declarations from the string. - std::string normalisedMath = std::regex_replace(math, xmlDeclaration, ""); + std::string normalisedMath = math; + size_t pos = 0; + while ((pos = normalisedMath.find("", pos + 5); + if (end != std::string::npos) { + normalisedMath.erase(pos, end + 2 - pos); + } else { + break; + } + } xmlDoc->parse("<" + wrapElementName + ">" + normalisedMath + ""); if (xmlDoc->xmlErrorCount() == 0) { auto rootNode = xmlDoc->rootNode(); @@ -146,8 +151,28 @@ std::string Printer::PrinterImpl::printMath(const std::string &math) childNode = childNode->next(); } // Clean whitespace in the math. - result = std::regex_replace(result, before, ">"); - return std::regex_replace(result, after, "<"); + std::string cleaned; + cleaned.reserve(result.size()); + bool afterGt = false; + for (char c : result) { + if (c == '>') { + cleaned += c; + afterGt = true; + } else if (afterGt && std::isspace(static_cast(c))) { + // Skip whitespace after >. + } else if (c == '<') { + afterGt = false; + // Trim whitespace before <. + while (!cleaned.empty() && std::isspace(static_cast(cleaned.back()))) { + cleaned.pop_back(); + } + cleaned += c; + } else { + afterGt = false; + cleaned += c; + } + } + return cleaned; } else { for (size_t i = 0; i < xmlDoc->xmlErrorCount(); ++i) { auto issue = Issue::IssueImpl::create(); @@ -160,37 +185,37 @@ std::string Printer::PrinterImpl::printMath(const std::string &math) return ""; } -void buildMapsForComponentsVariables(const ComponentPtr &component, ComponentMap &componentMap, VariableMap &variableMap) +using SeenPairsSet = std::set>; + +void buildMapsForComponentsVariables(const ComponentPtr &component, ComponentMap &componentMap, VariableMap &variableMap, SeenPairsSet &seenPairs) { for (size_t i = 0; i < component->variableCount(); ++i) { VariablePtr variable = component->variable(i); for (size_t j = 0; j < variable->equivalentVariableCount(); ++j) { VariablePtr equivalentVariable = variable->equivalentVariable(j); - VariablePairPtr variablePair = VariablePair::create(variable, equivalentVariable); - auto pairFound = std::find_if(variableMap.begin(), variableMap.end(), - [variable, equivalentVariable](const VariablePairPtr &in) { - return (in->variable1() == equivalentVariable) && (in->variable2() == variable); - }); - if (pairFound == variableMap.end()) { + // Check for the reverse pair (equivalentVariable, variable) to avoid duplicates. + auto reverseKey = std::make_pair(equivalentVariable.get(), variable.get()); + if (seenPairs.find(reverseKey) == seenPairs.end()) { // Add new unique variable equivalence pair to the VariableMap. - variableMap.push_back(variablePair); + variableMap.push_back(VariablePair::create(variable, equivalentVariable)); + // Record the forward pair as seen. + seenPairs.insert(std::make_pair(variable.get(), equivalentVariable.get())); // Get parent components. ComponentPtr component1 = owningComponent(variable); ComponentPtr component2 = owningComponent(equivalentVariable); // Also create a component map pair corresponding with the variable map pair. - ComponentPair componentPair = std::make_pair(component1, component2); - componentMap.push_back(componentPair); + componentMap.emplace_back(std::move(component1), std::move(component2)); } } } } -void buildMaps(const ComponentEntityPtr &componentEntity, ComponentMap &componentMap, VariableMap &variableMap) +void buildMaps(const ComponentEntityPtr &componentEntity, ComponentMap &componentMap, VariableMap &variableMap, SeenPairsSet &seenPairs) { for (size_t i = 0; i < componentEntity->componentCount(); ++i) { ComponentPtr component = componentEntity->component(i); - buildMapsForComponentsVariables(component, componentMap, variableMap); - buildMaps(component, componentMap, variableMap); + buildMapsForComponentsVariables(component, componentMap, variableMap, seenPairs); + buildMaps(component, componentMap, variableMap, seenPairs); } } @@ -198,21 +223,24 @@ std::string Printer::PrinterImpl::printUnits(const UnitsPtr &units, IdList &idLi { std::string repr; if (!units->isImport() && !isStandardUnit(units)) { + const auto unitCount = units->unitCount(); + repr.reserve(64 + 128 * unitCount); bool endTag = false; repr += "name(); if (!unitsName.empty()) { repr += " name=\"" + unitsName + "\""; } - if (!units->id().empty()) { - repr += " id=\"" + units->id() + "\""; + auto unitsId = units->id(); + if (!unitsId.empty()) { + repr += " id=\"" + unitsId + "\""; } else if (autoIds) { repr += " id=\"" + makeUniqueId(idList) + "\""; } - if (units->unitCount() > 0) { + if (unitCount > 0) { endTag = true; repr += ">"; - for (size_t i = 0; i < units->unitCount(); ++i) { + for (size_t i = 0; i < unitCount; ++i) { std::string reference; std::string prefix; std::string id; @@ -257,8 +285,9 @@ std::string Printer::PrinterImpl::printComponent(const ComponentPtr &component, if (!componentName.empty()) { repr += " name=\"" + componentName + "\""; } - if (!component->id().empty()) { - repr += " id=\"" + component->id() + "\""; + auto componentId = component->id(); + if (!componentId.empty()) { + repr += " id=\"" + componentId + "\""; } else if (autoIds) { repr += " id=\"" + makeUniqueId(idList) + "\""; } @@ -436,17 +465,16 @@ std::string Printer::PrinterImpl::printImports(const ModelPtr &model, IdList &id std::string repr; std::vector collatedImportSources; + std::unordered_set seenImportSources; auto importedComponents = getImportedComponents(model); for (auto &component : importedComponents) { - auto result = std::find(collatedImportSources.begin(), collatedImportSources.end(), component->importSource()); - if (result == collatedImportSources.end()) { + if (seenImportSources.insert(component->importSource().get()).second) { collatedImportSources.push_back(component->importSource()); } } auto importedUnits = getImportedUnits(model); for (auto &units : importedUnits) { - auto result = std::find(collatedImportSources.begin(), collatedImportSources.end(), units->importSource()); - if (result == collatedImportSources.end()) { + if (seenImportSources.insert(units->importSource().get()).second) { collatedImportSources.push_back(units->importSource()); } } @@ -462,8 +490,9 @@ std::string Printer::PrinterImpl::printImports(const ModelPtr &model, IdList &id for (const UnitsPtr &units : importedUnits) { if (units->importSource() == importSource) { repr += "importReference() + "\" name=\"" + units->name() + "\""; - if (!units->id().empty()) { - repr += " id=\"" + units->id() + "\""; + auto unitsId = units->id(); + if (!unitsId.empty()) { + repr += " id=\"" + unitsId + "\""; } else if (autoIds) { repr += " id=\"" + makeUniqueId(idList) + "\""; } @@ -473,8 +502,9 @@ std::string Printer::PrinterImpl::printImports(const ModelPtr &model, IdList &id for (const ComponentPtr &component : importedComponents) { if (component->importSource() == importSource) { repr += "importReference() + "\" name=\"" + component->name() + "\""; - if (!component->id().empty()) { - repr += " id=\"" + component->id() + "\""; + auto componentId = component->id(); + if (!componentId.empty()) { + repr += " id=\"" + componentId + "\""; } else if (autoIds) { repr += " id=\"" + makeUniqueId(idList) + "\""; } @@ -521,11 +551,13 @@ std::string Printer::printModel(const ModelPtr &model, bool autoIds) std::string repr; repr += "name().empty()) { - repr += " name=\"" + model->name() + "\""; + auto modelName = model->name(); + if (!modelName.empty()) { + repr += " name=\"" + modelName + "\""; } - if (!model->id().empty()) { - repr += " id=\"" + model->id() + "\""; + auto modelId = model->id(); + if (!modelId.empty()) { + repr += " id=\"" + modelId + "\""; } else if (autoIds) { repr += " id=\"" + makeUniqueId(idList) + "\""; } @@ -557,8 +589,9 @@ std::string Printer::printModel(const ModelPtr &model, bool autoIds) VariableMap variableMap; ComponentMap componentMap; + SeenPairsSet seenPairs; // Build unique variable equivalence pairs (ComponentMap, VariableMap) for connections. - buildMaps(model, componentMap, variableMap); + buildMaps(model, componentMap, variableMap, seenPairs); // Serialise connections of the model. repr += printConnections(componentMap, variableMap, idList, autoIds); diff --git a/src/reset.cpp b/src/reset.cpp index d334688d9..94c6283b5 100644 --- a/src/reset.cpp +++ b/src/reset.cpp @@ -104,7 +104,7 @@ void Reset::appendTestValue(const std::string &math) pFunc()->mTestValue.append(math); } -std::string Reset::testValue() const +const std::string &Reset::testValue() const { return pFunc()->mTestValue; } @@ -119,7 +119,7 @@ void Reset::removeTestValueId() pFunc()->mTestValueId = ""; } -std::string Reset::testValueId() const +const std::string &Reset::testValueId() const { return pFunc()->mTestValueId; } @@ -139,7 +139,7 @@ void Reset::appendResetValue(const std::string &math) pFunc()->mResetValue.append(math); } -std::string Reset::resetValue() const +const std::string &Reset::resetValue() const { return pFunc()->mResetValue; } @@ -164,7 +164,7 @@ void Reset::removeResetValueId() pFunc()->mResetValueId = ""; } -std::string Reset::resetValueId() const +const std::string &Reset::resetValueId() const { return pFunc()->mResetValueId; } diff --git a/src/units.cpp b/src/units.cpp index 2cddc0811..c684bfe85 100644 --- a/src/units.cpp +++ b/src/units.cpp @@ -93,7 +93,7 @@ static const std::map standardUnitToStri std::vector::const_iterator Units::UnitsImpl::findUnit(const std::string &reference) const { return std::find_if(mUnitDefinitions.begin(), mUnitDefinitions.end(), - [=](const UnitDefinition &u) -> bool { return u.mReference == reference; }); + [&](const UnitDefinition &u) -> bool { return u.mReference == reference; }); } Units::UnitsImpl *Units::pFunc() @@ -433,15 +433,20 @@ void Units::unitAttributes(const std::string &reference, std::string &prefix, do void Units::unitAttributes(size_t index, std::string &reference, std::string &prefix, double &exponent, double &multiplier, std::string &id) const { - UnitDefinition ud; if (index < pFunc()->mUnitDefinitions.size()) { - ud = pFunc()->mUnitDefinitions.at(index); + const auto &ud = pFunc()->mUnitDefinitions[index]; + reference = ud.mReference; + prefix = ud.mPrefix; + exponent = ud.mExponent; + multiplier = ud.mMultiplier; + id = ud.mId; + } else { + reference.clear(); + prefix.clear(); + exponent = 1.0; + multiplier = 1.0; + id.clear(); } - reference = ud.mReference; - prefix = ud.mPrefix; - exponent = ud.mExponent; - multiplier = ud.mMultiplier; - id = ud.mId; } std::string Units::unitAttributeReference(size_t index) const @@ -458,9 +463,7 @@ std::string Units::unitAttributeReference(size_t index) const void Units::setUnitAttributeReference(size_t index, const std::string &reference) { if (index < pFunc()->mUnitDefinitions.size()) { - UnitDefinition unitDefinition = pFunc()->mUnitDefinitions.at(index); - unitDefinition.mReference = reference; - pFunc()->mUnitDefinitions[index] = unitDefinition; + pFunc()->mUnitDefinitions[index].mReference = reference; } } diff --git a/src/utilities.cpp b/src/utilities.cpp index b58939173..f51eba4a5 100644 --- a/src/utilities.cpp +++ b/src/utilities.cpp @@ -19,11 +19,12 @@ limitations under the License. #include #include #include +#include #include #include #include -#include #include +#include #include #include "libcellml/analyserequation.h" @@ -102,6 +103,9 @@ bool hasNonWhitespaceCharacters(const std::string &input) Strings split(const std::string &content, const std::string &delimiter) { Strings strings; + + strings.reserve(content.length() / (delimiter.length() + 4) + 1); + size_t current; size_t previous = 0; current = content.find(delimiter); @@ -166,22 +170,17 @@ int convertPrefixToInt(const std::string &in, bool *ok) std::string convertToString(size_t value) { - std::ostringstream strs; - strs << value; - return strs.str(); + return std::format("{}", value); } std::string convertToString(int value) { - std::ostringstream strs; - strs << value; - return strs.str(); + return std::format("{}", value); } bool isEuropeanNumericCharacter(char c) { - const std::set validIntegerCharacters = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; - return validIntegerCharacters.find(c) != validIntegerCharacters.end(); + return c >= '0' && c <= '9'; } bool isNonNegativeCellMLInteger(const std::string &candidate) @@ -208,6 +207,9 @@ bool isCellMLExponent(const std::string &candidate) std::vector findOccurrences(const std::string &candidate, const std::string &sub) { std::vector occurrences; + + occurrences.reserve(candidate.length() / sub.length()); + size_t pos = candidate.find(sub, 0); while (pos != std::string::npos) { occurrences.push_back(pos); @@ -667,15 +669,15 @@ EquivalenceMap rebaseEquivalenceMap(const EquivalenceMap &map, const IndexStack { EquivalenceMap rebasedMap; for (const auto &entry : map) { - auto key = entry.first; + const auto &key = entry.first; auto rebasedKey = rebaseIndexStack(key, originStack, destinationStack); - auto vector = entry.second; + const auto &vector = entry.second; std::vector rebasedVector; - for (auto stack : vector) { + for (const auto &stack : vector) { // Temporarily remove the variable index whilst we rebase the component part of the stack. size_t variableIndex = stack.back(); - stack.pop_back(); - auto rebasedTarget = rebaseIndexStack(stack, originStack, destinationStack); + IndexStack componentStack(stack.begin(), stack.end() - 1); + auto rebasedTarget = rebaseIndexStack(componentStack, originStack, destinationStack); if (!rebasedTarget.empty()) { rebasedTarget.push_back(variableIndex); rebasedVector.push_back(rebasedTarget); @@ -827,9 +829,6 @@ void recordVariableEquivalences(const ComponentPtr &component, EquivalenceMap &e } auto equivalentVariable = variable->equivalentVariable(j); auto equivalentVariableIndexStack = indexStackOf(equivalentVariable); - if (equivalenceMap.count(indexStack) == 0) { - equivalenceMap.emplace(indexStack, std::vector()); - } equivalenceMap[indexStack].push_back(equivalentVariableIndexStack); } if (variable->equivalentVariableCount() > 0) { @@ -1035,15 +1034,15 @@ ConnectionMap createConnectionMap(const VariablePtr &variable1, const VariablePt return map; } -void recursiveEquivalentVariables(const VariablePtr &variable, std::vector &equivalentVariables) +void recursiveEquivalentVariables(const VariablePtr &variable, std::vector &equivalentVariables, std::unordered_set &seen) { for (size_t i = 0; i < variable->equivalentVariableCount(); ++i) { VariablePtr equivalentVariable = variable->equivalentVariable(i); - if (std::find(equivalentVariables.begin(), equivalentVariables.end(), equivalentVariable) == equivalentVariables.end()) { + if (seen.insert(equivalentVariable.get()).second) { equivalentVariables.push_back(equivalentVariable); - recursiveEquivalentVariables(equivalentVariable, equivalentVariables); + recursiveEquivalentVariables(equivalentVariable, equivalentVariables, seen); } } } @@ -1051,8 +1050,9 @@ void recursiveEquivalentVariables(const VariablePtr &variable, std::vector equivalentVariables(const VariablePtr &variable) { std::vector res = {variable}; + std::unordered_set seen = {variable.get()}; - recursiveEquivalentVariables(variable, res); + recursiveEquivalentVariables(variable, res, seen); return res; } @@ -1075,11 +1075,11 @@ bool linkComponentVariableUnits(const ComponentPtr &component, DescriptionList & if (model->hasUnits(u->name())) { v->setUnits(model->units(u->name())); } else { - descriptionList.push_back(std::make_pair(v, "Model does not contain the units '" + u->name() + "' required by variable '" + v->name() + "' in component '" + component->name() + "'.")); + descriptionList.emplace_back(v, "Model does not contain the units '" + u->name() + "' required by variable '" + v->name() + "' in component '" + component->name() + "'."); status = false; } } else if (model != nullptr) { - descriptionList.push_back(std::make_pair(v, "The units '" + u->name() + "' assigned to variable '" + v->name() + "' in component '" + component->name() + "' belong to a different model, '" + model->name() + "'.")); + descriptionList.emplace_back(v, "The units '" + u->name() + "' assigned to variable '" + v->name() + "' in component '" + component->name() + "' belong to a different model, '" + model->name() + "'."); status = false; } } @@ -1234,6 +1234,7 @@ std::string formDescriptionOfCyclicDependency(const History &history, const std: HistoryEpochPtr h; size_t i = 0; std::string msgHistory; + msgHistory.reserve(history.size() * 160); while (i < history.size()) { h = history[i]; msgHistory += " - " + h->mType + " '" + h->mName + "' specifies an import from '" + h->mSourceUrl + "' to '" + h->mDestinationUrl + "'"; @@ -1317,10 +1318,8 @@ XmlNodePtr mathmlChildNode(const XmlNodePtr &node, size_t index) return res; } -std::vector analyserVariables(const AnalyserVariablePtr &analyserVariable) +const std::vector &analyserVariables(const AnalyserVariablePtr &analyserVariable) { - std::vector res; - switch (analyserVariable->type()) { case AnalyserVariable::Type::CONSTANT: return analyserVariable->analyserModel()->constants(); @@ -1333,26 +1332,27 @@ std::vector analyserVariables(const AnalyserVariablePtr &an break; } - return {}; + static const std::vector empty; + + return empty; } std::vector analyserVariables(const AnalyserModelPtr &analyserModel) { std::vector res; + const auto &states = analyserModel->states(); + const auto &constants = analyserModel->constants(); + const auto &computedConstants = analyserModel->computedConstants(); + const auto &algebraicVariables = analyserModel->algebraicVariables(); + const auto &externalVariables = analyserModel->externalVariables(); + + res.reserve((analyserModel->voi() != nullptr ? 1 : 0) + states.size() + constants.size() + computedConstants.size() + algebraicVariables.size() + externalVariables.size()); if (analyserModel->voi() != nullptr) { res.push_back(analyserModel->voi()); } - auto states = analyserModel->states(); - res.insert(res.end(), states.begin(), states.end()); - - auto constants = analyserModel->constants(); - auto computedConstants = analyserModel->computedConstants(); - auto algebraicVariables = analyserModel->algebraicVariables(); - auto externalVariables = analyserModel->externalVariables(); - res.insert(res.end(), constants.begin(), constants.end()); res.insert(res.end(), computedConstants.begin(), computedConstants.end()); res.insert(res.end(), algebraicVariables.begin(), algebraicVariables.end()); @@ -1363,11 +1363,16 @@ std::vector analyserVariables(const AnalyserModelPtr &analy std::vector analyserVariables(const AnalyserEquationPtr &analyserEquation) { - auto res = analyserEquation->states(); - auto computedConstants = analyserEquation->computedConstants(); - auto algebraicVariables = analyserEquation->algebraicVariables(); - auto externalVariables = analyserEquation->externalVariables(); + const auto &states = analyserEquation->states(); + const auto &computedConstants = analyserEquation->computedConstants(); + const auto &algebraicVariables = analyserEquation->algebraicVariables(); + const auto &externalVariables = analyserEquation->externalVariables(); + + std::vector res; + res.reserve(states.size() + computedConstants.size() + algebraicVariables.size() + externalVariables.size()); + + res.insert(res.end(), states.begin(), states.end()); res.insert(res.end(), computedConstants.begin(), computedConstants.end()); res.insert(res.end(), algebraicVariables.begin(), algebraicVariables.end()); res.insert(res.end(), externalVariables.begin(), externalVariables.end()); diff --git a/src/utilities.h b/src/utilities.h index 888447f1f..4eb0c82e6 100644 --- a/src/utilities.h +++ b/src/utilities.h @@ -879,7 +879,7 @@ XmlNodePtr mathmlChildNode(const XmlNodePtr &node, size_t index); * * @return The analyser variables of the same type as the given analyser variable. */ -std::vector analyserVariables(const AnalyserVariablePtr &analyserVariable); +const std::vector &analyserVariables(const AnalyserVariablePtr &analyserVariable); /** * @brief Return the analyser variables in the given analyser model. diff --git a/src/validator.cpp b/src/validator.cpp index 55a1db118..ab8d04a26 100644 --- a/src/validator.cpp +++ b/src/validator.cpp @@ -18,12 +18,13 @@ limitations under the License. #include #include +#include #include #include -#include -#include #include #include +#include +#include #include "libcellml/importsource.h" #include "libcellml/reset.h" @@ -308,7 +309,7 @@ class Validator::ValidatorImpl: public LoggerImpl * @param component The component to validate the name of. * @param names The list of component names already used in the model. */ - void validateUniqueName(const ModelPtr &model, const ComponentPtr &component, NameList &names); + void validateUniqueName(const ModelPtr &model, const ComponentPtr &component, std::unordered_set &namesSet); /** * @brief Validate the @p component using the CellML 2.0 Specification. @@ -334,7 +335,7 @@ class Validator::ValidatorImpl: public LoggerImpl * @param history The history of visited components. * @param modelsVisited The list of visited models. */ - void validateComponentTree(const ModelPtr &model, const ComponentPtr &component, NameList &componentNames, History &history, std::vector &modelsVisited); + void validateComponentTree(const ModelPtr &model, const ComponentPtr &component, std::unordered_set &componentNames, History &history, std::vector &modelsVisited); /** * @brief Validate the @p units using the CellML 2.0 Specification. @@ -412,7 +413,7 @@ class Validator::ValidatorImpl: public LoggerImpl * @param variable The variable to validate. * @param variableNames A vector list of the name attributes of the @p variable and its siblings. */ - void validateVariable(const VariablePtr &variable, const NameList &variableNames); + void validateVariable(const VariablePtr &variable, const std::unordered_set &variableNames); /** * @brief Validate the @p reset using the CellML 2.0 Specification. @@ -477,7 +478,7 @@ class Validator::ValidatorImpl: public LoggerImpl * @param component The component the @p node is a part of. * @param variableNames A list of variable names. */ - void validateAndCleanCiNode(const XmlNodePtr &node, const ComponentPtr &component, const NameList &variableNames); + void validateAndCleanCiNode(const XmlNodePtr &node, const ComponentPtr &component, const std::unordered_set &variableNames); /** * @brief Validate the text of a @c cn element. @@ -503,7 +504,7 @@ class Validator::ValidatorImpl: public LoggerImpl * @param component The component that the math @c XmlNode @p node is contained within. * @param variableNames A @c vector list of the names of variables found within the @p component. */ - void validateAndCleanMathCiCnNodes(XmlNodePtr &node, const ComponentPtr &component, const NameList &variableNames); + void validateAndCleanMathCiCnNodes(XmlNodePtr &node, const ComponentPtr &component, const std::unordered_set &variableNames); /** * @brief Add a MathML-related issue. @@ -640,7 +641,7 @@ class Validator::ValidatorImpl: public LoggerImpl * @param idMap The IdMap object to construct. * @param reportedConnections A set of connection identifiers to prevent duplicate reporting. */ - void buildComponentIdMap(const ComponentPtr &component, IdMap &idMap, std::set &reportedConnections); + void buildComponentIdMap(const ComponentPtr &component, IdMap &idMap, std::unordered_set &reportedConnections); /** @brief Utility function to add an item to the idMap. * @@ -728,7 +729,7 @@ class Validator::ValidatorImpl: public LoggerImpl bool checkForLocalCycles(const History &history, const HistoryEpochPtr &h) { return std::find_if(history.begin(), history.end(), - [=](const HistoryEpochPtr &i) -> bool { return (i->mName == h->mName) && (i->mSourceUrl == h->mSourceUrl); }) + [&](const HistoryEpochPtr &i) -> bool { return (i->mName == h->mName) && (i->mSourceUrl == h->mSourceUrl); }) != history.end(); } @@ -765,25 +766,27 @@ void Validator::validateModel(const ModelPtr &model) pFunc()->addIssue(issue); } else { // Check for a valid name attribute. - if (!isCellmlIdentifier(model->name())) { - auto issue = pFunc()->makeIssueIllegalIdentifier(model->name()); + const auto &modelName = model->name(); + if (!isCellmlIdentifier(modelName)) { + auto issue = pFunc()->makeIssueIllegalIdentifier(modelName); issue->mPimpl->mItem->mPimpl->setModel(model); issue->mPimpl->setReferenceRule(Issue::ReferenceRule::MODEL_NAME_VALUE); - issue->mPimpl->setDescription("Model '" + model->name() + "' does not have a valid name attribute. " + issue->description()); + issue->mPimpl->setDescription("Model '" + modelName + "' does not have a valid name attribute. " + issue->description()); pFunc()->addIssue(issue); } // Check for a valid identifier. - if (!isValidXmlName(model->id())) { + const auto &modelId = model->id(); + if (!isValidXmlName(modelId)) { auto issue = Issue::IssueImpl::create(); issue->mPimpl->setReferenceRule(Issue::ReferenceRule::XML_ID_ATTRIBUTE); issue->mPimpl->mItem->mPimpl->setModel(model); - issue->mPimpl->setDescription("Model '" + model->name() + "' does not have a valid 'id' attribute, '" + model->id() + "'."); + issue->mPimpl->setDescription("Model '" + modelName + "' does not have a valid 'id' attribute, '" + modelId + "'."); pFunc()->addIssue(issue); } std::vector modelsVisited = {model}; // Check for components in this model. if (model->componentCount() > 0) { - NameList componentNames; + std::unordered_set componentNames; History history; for (size_t i = 0; i < model->componentCount(); ++i) { history.clear(); @@ -811,11 +814,11 @@ void Validator::validateModel(const ModelPtr &model) } } -void Validator::ValidatorImpl::validateUniqueName(const ModelPtr &model, const ComponentPtr &component, NameList &names) +void Validator::ValidatorImpl::validateUniqueName(const ModelPtr &model, const ComponentPtr &component, std::unordered_set &namesSet) { std::string name = component->name(); if (!name.empty()) { - if (std::find(names.begin(), names.end(), name) != names.end()) { + if (!namesSet.insert(name).second) { auto issue = Issue::IssueImpl::create(); issue->mPimpl->setDescription("Model '" + model->name() + "' contains multiple components with the name '" + name + "'. Valid component names must be unique to their model."); issue->mPimpl->mItem->mPimpl->setModel(model); @@ -825,13 +828,11 @@ void Validator::ValidatorImpl::validateUniqueName(const ModelPtr &model, const C issue->mPimpl->setReferenceRule(Issue::ReferenceRule::COMPONENT_NAME_UNIQUE); } addIssue(issue); - } else { - names.push_back(name); } } } -void Validator::ValidatorImpl::validateComponentTree(const ModelPtr &model, const ComponentPtr &component, NameList &componentNames, History &history, std::vector &modelsVisited) +void Validator::ValidatorImpl::validateComponentTree(const ModelPtr &model, const ComponentPtr &component, std::unordered_set &componentNames, History &history, std::vector &modelsVisited) { validateUniqueName(model, component, componentNames); for (size_t i = 0; i < component->componentCount(); ++i) { @@ -1018,12 +1019,12 @@ void Validator::ValidatorImpl::validateComponent(const ComponentPtr &component, } } else { // Check for variables in this component. - NameList variableNames; + std::unordered_set variableNames; // Validate variable(s). for (size_t i = 0; i < component->variableCount(); ++i) { VariablePtr variable = component->variable(i); validateVariable(variable, variableNames); - variableNames.push_back(variable->name()); + variableNames.insert(variable->name()); } // Check for resets in this component. for (size_t i = 0; i < component->resetCount(); ++i) { @@ -1040,12 +1041,12 @@ void Validator::ValidatorImpl::validateComponent(const ComponentPtr &component, handleErrorsFromImports(initialIssueCount, isOriginatingModel, "Component", componentName, history, component, nullptr); } -std::set namesInCycle(NameList allNames) +std::unordered_set namesInCycle(NameList allNames) { std::string cycleStartName = allNames.back(); allNames.pop_back(); std::reverse(allNames.begin(), allNames.end()); - std::set namesInCycle = {cycleStartName}; + std::unordered_set namesInCycle = {cycleStartName}; std::string name = *allNames.begin(); while (name != cycleStartName) { namesInCycle.emplace(name); @@ -1058,7 +1059,7 @@ std::set namesInCycle(NameList allNames) bool Validator::ValidatorImpl::hasCycleAlreadyBeenReported(NameList names) const { - std::set testNamesInCycle = namesInCycle(std::move(names)); + std::unordered_set testNamesInCycle = namesInCycle(std::move(names)); bool found = false; for (size_t i = 0; !found && (i < mValidator->issueCount()); ++i) { auto issue = mValidator->issue(i); @@ -1277,14 +1278,16 @@ void Validator::ValidatorImpl::validateUnitsUnitsItem(size_t index, const UnitsP units->unitAttributes(index, reference, prefix, exponent, multiplier, id); if (isCellmlIdentifier(reference)) { ModelPtr model = owningModel(units); - if (model->hasUnits(reference) && !isStandardUnitName(reference)) { - validateUnits(model->units(reference), history, modelsVisited); - } else if (!model->hasUnits(reference) && !isStandardUnitName(reference)) { - auto issue = Issue::IssueImpl::create(); - issue->mPimpl->setDescription("Units reference '" + reference + "' in units '" + units->name() + "' is not a valid reference to a local units or a standard unit type."); - issue->mPimpl->mItem->mPimpl->setUnitsItem(UnitsItem::create(units, index)); - issue->mPimpl->setReferenceRule(Issue::ReferenceRule::UNIT_UNITS_REFERENCE); - addIssue(issue); + if (!isStandardUnitName(reference)) { + if (model->hasUnits(reference)) { + validateUnits(model->units(reference), history, modelsVisited); + } else { + auto issue = Issue::IssueImpl::create(); + issue->mPimpl->setDescription("Units reference '" + reference + "' in units '" + units->name() + "' is not a valid reference to a local units or a standard unit type."); + issue->mPimpl->mItem->mPimpl->setUnitsItem(UnitsItem::create(units, index)); + issue->mPimpl->setReferenceRule(Issue::ReferenceRule::UNIT_UNITS_REFERENCE); + addIssue(issue); + } } } else { auto issue = makeIssueIllegalIdentifier(reference); @@ -1325,12 +1328,12 @@ void Validator::ValidatorImpl::validateUnitsUnitsItem(size_t index, const UnitsP } } -void Validator::ValidatorImpl::validateVariable(const VariablePtr &variable, const NameList &variableNames) +void Validator::ValidatorImpl::validateVariable(const VariablePtr &variable, const std::unordered_set &variableNames) { ComponentPtr component = owningComponent(variable); auto variableName = variable->name(); if (!variableName.empty()) { - if (std::find(variableNames.begin(), variableNames.end(), variableName) != variableNames.end()) { + if (variableNames.count(variableName) != 0) { auto issue = Issue::IssueImpl::create(); issue->mPimpl->setDescription("Component '" + component->name() + "' contains multiple variables with the name '" + variableName + "'. Valid variable names must be unique to their component."); issue->mPimpl->mItem->mPimpl->setComponent(component); @@ -1422,6 +1425,7 @@ void Validator::ValidatorImpl::validateReset(const ResetPtr &reset, const Compon std::string testVarParentName; std::string description = "Reset in component '" + component->name() + "' "; + description.reserve(256 + component->name().size()); if (reset->isOrderSet()) { description += "with order '" + convertToString(reset->order()) + "', "; @@ -1579,12 +1583,9 @@ void Validator::ValidatorImpl::validateMath(const std::string &input, const Comp } XmlNodePtr nodeCopy = node; - NameList variableNames; + std::unordered_set variableNames; for (size_t i = 0; i < component->variableCount(); ++i) { - std::string variableName = component->variable(i)->name(); - if (std::find(variableNames.begin(), variableNames.end(), variableName) == variableNames.end()) { - variableNames.push_back(variableName); - } + variableNames.insert(component->variable(i)->name()); } validateMathMLElements(nodeCopy, component); @@ -1709,13 +1710,13 @@ void Validator::ValidatorImpl::validateAndCleanCnNode(const XmlNodePtr &node, co } } -void Validator::ValidatorImpl::validateAndCleanCiNode(const XmlNodePtr &node, const ComponentPtr &component, const NameList &variableNames) +void Validator::ValidatorImpl::validateAndCleanCiNode(const XmlNodePtr &node, const ComponentPtr &component, const std::unordered_set &variableNames) { XmlNodePtr childNode = node->firstChild(); std::string textInNode = text(childNode); if (!textInNode.empty()) { // Check whether we can find this text as a variable name in this component. - if (std::find(variableNames.begin(), variableNames.end(), textInNode) == variableNames.end()) { + if (variableNames.count(textInNode) == 0) { auto issue = Issue::IssueImpl::create(); issue->mPimpl->setDescription("MathML ci element has the child text '" + textInNode + "' which does not correspond with any variable names present in component '" + component->name() + "'."); issue->mPimpl->mItem->mPimpl->setMath(component); @@ -1725,7 +1726,7 @@ void Validator::ValidatorImpl::validateAndCleanCiNode(const XmlNodePtr &node, co } } -void Validator::ValidatorImpl::validateAndCleanMathCiCnNodes(XmlNodePtr &node, const ComponentPtr &component, const NameList &variableNames) +void Validator::ValidatorImpl::validateAndCleanMathCiCnNodes(XmlNodePtr &node, const ComponentPtr &component, const std::unordered_set &variableNames) { if (node->isMathmlElement("cn")) { validateAndCleanCnNode(node, component); @@ -2448,8 +2449,9 @@ void Validator::ValidatorImpl::validateConnections(const ModelPtr &model) bool Validator::ValidatorImpl::isSupportedMathMLElement(const XmlNodePtr &node) const { - return (node->namespaceUri() == MATHML_NS) - && std::find(supportedMathMLElements.begin(), supportedMathMLElements.end(), node->name()) != supportedMathMLElements.end(); + static const std::unordered_set supportedMathMLElementsSet(supportedMathMLElements.begin(), supportedMathMLElements.end()); + + return node->isMathmlElement() && supportedMathMLElementsSet.count(node->rawName()) != 0; } IssuePtr Validator::ValidatorImpl::makeIssueIllegalIdentifier(const std::string &name) const @@ -2478,7 +2480,7 @@ bool unitsAreEquivalent(const ModelPtr &model, std::string &hints, double &multiplier) { - std::map unitMap = {}; + std::map unitMap; for (const auto &baseUnits : baseUnitsList) { unitMap.emplace(baseUnits, 0.0); @@ -2489,37 +2491,36 @@ bool unitsAreEquivalent(const ModelPtr &model, std::string v1UnitsName = v1->units()->name(); if (model->hasUnits(v1UnitsName)) { - UnitsPtr u1 = Units::create(); - u1 = model->units(v1UnitsName); + auto u1 = model->units(v1UnitsName); updateBaseUnitCount(model, unitMap, multiplier, u1->name(), 1, 0, 1); - } else if (unitMap.find(v1UnitsName) != unitMap.end()) { - unitMap.at(v1UnitsName) += 1.0; - } else if (isStandardUnitName(v1UnitsName)) { - updateBaseUnitCount(model, unitMap, multiplier, v1UnitsName, 1, 0, 1); + } else { + auto it = unitMap.find(v1UnitsName); + if (it != unitMap.end()) { + it->second += 1.0; + } else if (isStandardUnitName(v1UnitsName)) { + updateBaseUnitCount(model, unitMap, multiplier, v1UnitsName, 1, 0, 1); + } } std::string v2UnitsName = v2->units()->name(); if (model->hasUnits(v2UnitsName)) { - UnitsPtr u2 = Units::create(); - u2 = model->units(v2UnitsName); + auto u2 = model->units(v2UnitsName); updateBaseUnitCount(model, unitMap, multiplier, u2->name(), 1, 0, -1); - } else if (unitMap.find(v2UnitsName) != unitMap.end()) { - unitMap.at(v2UnitsName) -= 1.0; - } else if (isStandardUnitName(v2UnitsName)) { - updateBaseUnitCount(model, unitMap, multiplier, v2UnitsName, 1, 0, -1); + } else { + auto it = unitMap.find(v2UnitsName); + if (it != unitMap.end()) { + it->second -= 1.0; + } else if (isStandardUnitName(v2UnitsName)) { + updateBaseUnitCount(model, unitMap, multiplier, v2UnitsName, 1, 0, -1); + } } // Remove "dimensionless" from base unit testing. unitMap.erase("dimensionless"); - static const std::regex fullStopAtEndRegex(".$"); - bool status = true; for (const auto &basePair : unitMap) { if (basePair.second != 0.0) { - std::string num = std::to_string(basePair.second); - num.erase(num.find_last_not_of('0') + 1, num.length()); - num = std::regex_replace(num, fullStopAtEndRegex, ""); - hints += basePair.first + "^" + num + ", "; + hints += basePair.first + "^" + std::format("{}", basePair.second) + ", "; status = false; } } @@ -2528,10 +2529,7 @@ bool unitsAreEquivalent(const ModelPtr &model, // NB: multiplication issues are only reported when there is a base issue mismatch too, does not trigger it alone. // The multiplication mismatch will be returned through the multiplier argument in all cases. - std::string num = std::to_string(multiplier); - num.erase(num.find_last_not_of('0') + 1, num.length()); - num = std::regex_replace(num, fullStopAtEndRegex, ""); - hints += "multiplication factor of 10^" + num + ", "; + hints += "multiplication factor of 10^" + std::format("{}", multiplier) + ", "; } // Remove the final trailing comma from the hints string. @@ -2553,9 +2551,6 @@ void updateBaseUnitCount(const ModelPtr &model, if (model->hasUnits(uName)) { UnitsPtr u = model->units(uName); if (u->isBaseUnit()) { - if (unitMap.find(uName) == unitMap.end()) { - unitMap.emplace(uName, 0.0); - } unitMap[uName] += direction * uExp; multiplier += direction * logMult; } else { @@ -2593,7 +2588,7 @@ void Validator::ValidatorImpl::checkUniqueResetOrders(const ModelPtr &model) auto variable = variableOrder.first; auto orders = variableOrder.second; - std::set ordersSet(orders.begin(), orders.end()); + std::unordered_set ordersSet(orders.begin(), orders.end()); if (ordersSet.size() < orders.size()) { auto issue = Issue::IssueImpl::create(); @@ -2608,20 +2603,19 @@ void Validator::ValidatorImpl::checkUniqueResetOrders(const ModelPtr &model) void Validator::ValidatorImpl::addResetOrderMapItem(const VariablePtr &variable, int order, ResetOrderMap &resetOrderMap) { auto currentVariable = variable; - bool existingVariableFound = resetOrderMap.count(currentVariable) > 0; + auto it = resetOrderMap.find(currentVariable); size_t i = 0; - while ((i < variable->equivalentVariableCount()) && !existingVariableFound) { + while ((i < variable->equivalentVariableCount()) && (it == resetOrderMap.end())) { currentVariable = variable->equivalentVariable(i); - existingVariableFound = resetOrderMap.count(currentVariable) > 0; + it = resetOrderMap.find(currentVariable); ++i; } - if (existingVariableFound) { - resetOrderMap[currentVariable].emplace_back(order); + if (it != resetOrderMap.end()) { + it->second.emplace_back(order); } else { - std::vector orders = {order}; - resetOrderMap.emplace(variable, orders); + resetOrderMap.emplace(variable, std::vector {order}); } } @@ -2682,13 +2676,12 @@ void Validator::ValidatorImpl::checkUniqueIds(const ModelPtr &model) void Validator::ValidatorImpl::addIdMapItem(const std::string &id, const std::string &info, IdMap &idMap) { - if (idMap.count(id) > 0) { - idMap[id].second.emplace_back(info); - idMap[id] = std::make_pair(idMap[id].first + 1, idMap[id].second); + auto it = idMap.find(id); + if (it != idMap.end()) { + it->second.second.emplace_back(info); + ++it->second.first; } else { - Strings infos; - infos.emplace_back(info); - idMap.emplace(id, std::make_pair(1, infos)); + idMap.emplace(id, std::make_pair(1, Strings {info})); } } @@ -2696,7 +2689,7 @@ IdMap Validator::ValidatorImpl::buildModelIdMap(const ModelPtr &model) { IdMap idMap; std::string info; - std::set reportedConnections; + std::unordered_set reportedConnections; // Model. if (!model->id().empty()) { info = " - model '" + model->name() + "'"; @@ -2753,7 +2746,7 @@ IdMap Validator::ValidatorImpl::buildModelIdMap(const ModelPtr &model) return idMap; } -void Validator::ValidatorImpl::buildComponentIdMap(const ComponentPtr &component, IdMap &idMap, std::set &reportedConnections) +void Validator::ValidatorImpl::buildComponentIdMap(const ComponentPtr &component, IdMap &idMap, std::unordered_set &reportedConnections) { std::string info; @@ -2764,8 +2757,9 @@ void Validator::ValidatorImpl::buildComponentIdMap(const ComponentPtr &component if (component->isImport()) { imported = "imported "; } - if (owningComponent(component) != nullptr) { - owning = "' in component '" + owningComponent(component)->name() + "'"; + auto parent = owningComponent(component); + if (parent != nullptr) { + owning = "' in component '" + parent->name() + "'"; } else { owning = "' in model '" + owningModel(component)->name() + "'"; } @@ -2835,20 +2829,20 @@ void Validator::ValidatorImpl::buildComponentIdMap(const ComponentPtr &component for (size_t i = 0; i < component->resetCount(); ++i) { auto item = component->reset(i); if (!item->id().empty()) { - info = " - reset at index " + std::to_string(i) + " in component '" + component->name() + "'"; + info = " - reset at index " + std::format("{}", i) + " in component '" + component->name() + "'"; addIdMapItem(item->id(), info, idMap); } if (!item->testValueId().empty()) { - info = " - test_value in reset at index " + std::to_string(i) + " in component '" + component->name() + "'"; + info = " - test_value in reset at index " + std::format("{}", i) + " in component '" + component->name() + "'"; addIdMapItem(item->testValueId(), info, idMap); } - info = "test_value in reset " + std::to_string(i) + " in component '" + component->name() + "'"; + info = "test_value in reset " + std::format("{}", i) + " in component '" + component->name() + "'"; buildMathIdMap(info, idMap, item->testValue()); if (!item->resetValueId().empty()) { - info = " - reset_value in reset at index " + std::to_string(i) + " in component '" + component->name() + "'"; + info = " - reset_value in reset at index " + std::format("{}", i) + " in component '" + component->name() + "'"; addIdMapItem(item->resetValueId(), info, idMap); } - info = "reset_value in reset " + std::to_string(i) + " in component '" + component->name() + "'"; + info = "reset_value in reset " + std::format("{}", i) + " in component '" + component->name() + "'"; buildMathIdMap(info, idMap, item->resetValue()); } diff --git a/src/variable.cpp b/src/variable.cpp index 5644b6321..d9f4aa2d6 100644 --- a/src/variable.cpp +++ b/src/variable.cpp @@ -31,13 +31,13 @@ namespace libcellml { std::vector::const_iterator Variable::VariableImpl::findEquivalentVariable(const VariablePtr &equivalentVariable) const { return std::find_if(mEquivalentVariables.begin(), mEquivalentVariables.end(), - [=](const VariableWeakPtr &variableWeak) -> bool { return equivalentVariable == variableWeak.lock(); }); + [&](const VariableWeakPtr &variableWeak) -> bool { return equivalentVariable == variableWeak.lock(); }); } std::vector::iterator Variable::VariableImpl::findEquivalentVariable(const VariablePtr &equivalentVariable) { return std::find_if(mEquivalentVariables.begin(), mEquivalentVariables.end(), - [=](const VariableWeakPtr &variableWeak) -> bool { return equivalentVariable == variableWeak.lock(); }); + [&](const VariableWeakPtr &variableWeak) -> bool { return equivalentVariable == variableWeak.lock(); }); } Variable::VariableImpl *Variable::pFunc() @@ -178,7 +178,7 @@ bool Variable::hasEquivalentVariable(const VariablePtr &equivalentVariable, bool void Variable::VariableImpl::cleanExpiredVariables() { - mEquivalentVariables.erase(std::remove_if(mEquivalentVariables.begin(), mEquivalentVariables.end(), [=](const VariableWeakPtr &variableWeak) -> bool { return variableWeak.expired(); }), mEquivalentVariables.end()); + mEquivalentVariables.erase(std::remove_if(mEquivalentVariables.begin(), mEquivalentVariables.end(), [](const VariableWeakPtr &variableWeak) -> bool { return variableWeak.expired(); }), mEquivalentVariables.end()); } bool Variable::VariableImpl::hasEquivalentVariable(const VariablePtr &equivalentVariable, bool considerIndirectEquivalences) const @@ -342,7 +342,7 @@ void Variable::setInitialValue(const VariablePtr &variable) pFunc()->mInitialValue = variable->name(); } -std::string Variable::initialValue() const +const std::string &Variable::initialValue() const { return pFunc()->mInitialValue; } @@ -362,7 +362,7 @@ void Variable::setInterfaceType(Variable::InterfaceType interfaceType) setInterfaceType(interfaceTypeToString.at(interfaceType)); } -std::string Variable::interfaceType() const +const std::string &Variable::interfaceType() const { return pFunc()->mInterfaceType; } diff --git a/src/xmlattribute.cpp b/src/xmlattribute.cpp index dd5eeb2f4..d2d717279 100644 --- a/src/xmlattribute.cpp +++ b/src/xmlattribute.cpp @@ -69,13 +69,30 @@ std::string XmlAttribute::namespacePrefix() const bool XmlAttribute::inNamespaceUri(const char *ns) const { - return xmlStrcmp(reinterpret_cast(namespaceUri().c_str()), reinterpret_cast(ns)) == 0; + if (mPimpl->mXmlAttributePtr->ns == nullptr) { + // Note: we would normally have + // return (ns == nullptr) || (ns[0] == '\0'); + // but this is an internal function and we never pass in a null pointer or an empty string for the + // namespace, so we can just return false here. + return false; + } + return xmlStrcmp(mPimpl->mXmlAttributePtr->ns->href, reinterpret_cast(ns)) == 0; } bool XmlAttribute::isType(const char *name, const char *ns) const { - return (xmlStrcmp(reinterpret_cast(namespaceUri().c_str()), reinterpret_cast(ns)) == 0) - && (xmlStrcmp(mPimpl->mXmlAttributePtr->name, reinterpret_cast(name)) == 0); + if (mPimpl->mXmlAttributePtr->ns == nullptr) { + // Note: we would normally test for + // (ns != nullptr) && (ns[0] != '\0') + // but this is an internal function and we never pass in a null pointer for the namespace, so we can just + // test for an empty string here. + if (ns[0] != '\0') { + return false; + } + } else if (xmlStrcmp(mPimpl->mXmlAttributePtr->ns->href, reinterpret_cast(ns)) != 0) { + return false; + } + return xmlStrcmp(mPimpl->mXmlAttributePtr->name, reinterpret_cast(name)) == 0; } bool XmlAttribute::isCellmlType(const char *name) const diff --git a/src/xmldoc.cpp b/src/xmldoc.cpp index 24709be46..0187f5b50 100644 --- a/src/xmldoc.cpp +++ b/src/xmldoc.cpp @@ -16,10 +16,10 @@ limitations under the License. #include "xmldoc.h" +#include #include #include #include -#include #include #include #include @@ -44,9 +44,9 @@ namespace libcellml { */ void structuredErrorCallback(void *userData, XML_ERROR_CALLBACK_ARGUMENT_TYPE error) { - static const std::regex newLineRegex("\\n"); - // Swap libxml2 carriage return for a period. - std::string errorString = std::regex_replace(error->message, newLineRegex, "."); + // Swap libxml2 newlines for a period. + std::string errorString(error->message); + std::replace(errorString.begin(), errorString.end(), '\n', '.'); auto context = reinterpret_cast(userData); auto doc = reinterpret_cast(context->_private); doc->addXmlError(errorString); diff --git a/src/xmlnode.cpp b/src/xmlnode.cpp index 93a273ac0..8b6ee9954 100644 --- a/src/xmlnode.cpp +++ b/src/xmlnode.cpp @@ -157,13 +157,14 @@ XmlNamespaceMap XmlNode::definedNamespaces() const bool XmlNode::isElement(const char *name, const char *ns) const { - bool found = false; - if ((mPimpl->mXmlNodePtr->type == XML_ELEMENT_NODE) - && (xmlStrcmp(reinterpret_cast(namespaceUri().c_str()), reinterpret_cast(ns)) == 0) - && ((name == nullptr) || (xmlStrcmp(mPimpl->mXmlNodePtr->name, reinterpret_cast(name)) == 0))) { - found = true; + if (mPimpl->mXmlNodePtr->type != XML_ELEMENT_NODE) { + return false; } - return found; + if (mPimpl->mXmlNodePtr->ns == nullptr + || xmlStrcmp(mPimpl->mXmlNodePtr->ns->href, reinterpret_cast(ns)) != 0) { + return false; + } + return (name == nullptr) || (xmlStrcmp(mPimpl->mXmlNodePtr->name, reinterpret_cast(name)) == 0); } bool XmlNode::isElement() const @@ -227,33 +228,27 @@ std::string XmlNode::name() const return reinterpret_cast(mPimpl->mXmlNodePtr->name); } -bool XmlNode::hasAttribute(const char *attributeName) const +const char *XmlNode::rawName() const { - xmlAttrPtr attribute = xmlHasProp(mPimpl->mXmlNodePtr, reinterpret_cast(attributeName)); - return attribute != nullptr; -} - -xmlNsPtr getAttributeNamespace(const xmlNodePtr &node, const char *attributeName) -{ - return xmlHasProp(node, reinterpret_cast(attributeName))->ns; + return reinterpret_cast(mPimpl->mXmlNodePtr->name); } std::string XmlNode::attribute(const char *attributeName) const { - std::string attributeValueString; - if (hasAttribute(attributeName)) { - xmlChar *attributeValue = xmlGetProp(mPimpl->mXmlNodePtr, reinterpret_cast(attributeName)); - attributeValueString = std::string(reinterpret_cast(attributeValue)); + xmlChar *attributeValue = xmlGetProp(mPimpl->mXmlNodePtr, reinterpret_cast(attributeName)); + if (attributeValue != nullptr) { + std::string result(reinterpret_cast(attributeValue)); xmlFree(attributeValue); + return result; } - return attributeValueString; + return {}; } void XmlNode::setAttribute(const char *attributeName, const char *attributeValue) { - if (hasAttribute(attributeName)) { - auto ns = getAttributeNamespace(mPimpl->mXmlNodePtr, attributeName); - xmlSetNsProp(mPimpl->mXmlNodePtr, ns, reinterpret_cast(attributeName), reinterpret_cast(attributeValue)); + xmlAttrPtr attr = xmlHasProp(mPimpl->mXmlNodePtr, reinterpret_cast(attributeName)); + if (attr != nullptr) { + xmlSetNsProp(mPimpl->mXmlNodePtr, attr->ns, reinterpret_cast(attributeName), reinterpret_cast(attributeValue)); } } diff --git a/src/xmlnode.h b/src/xmlnode.h index 0d34b1e16..9f0120e04 100644 --- a/src/xmlnode.h +++ b/src/xmlnode.h @@ -289,18 +289,13 @@ class XmlNode std::string name() const; /** - * @brief Check if this @c XmlNode has the specified attribute. + * @brief Get the raw name of the XML element. * - * Checks whether this @c XmlNode has an attribute of the type - * specified by the argument @p attributeName. Returns @c true - * if so, and @c false otherwise. + * Get the raw name of the XML element as a C string pointer. * - * @param attributeName The @c char attribute type to check for. - * - * @return @c true if this @c XmlNode has an attribute of the type - * specified by the @p attributeName and @c false otherwise. + * @return A @c const @c char pointer to the XML element name. */ - bool hasAttribute(const char *attributeName) const; + const char *rawName() const; /** * @brief Get the attribute of the specified type for this @c XmlNode diff --git a/tests/coverage/coverage.cpp b/tests/coverage/coverage.cpp index 15b8699f0..67c7c721a 100644 --- a/tests/coverage/coverage.cpp +++ b/tests/coverage/coverage.cpp @@ -968,6 +968,31 @@ TEST(Coverage, generator) libcellml::Generator::equationCode(analyser->analyserModel()->analyserEquation(0)->ast()); } +TEST(Coverage, generatorVersionString) +{ + 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->analyserModel(); + auto generator = libcellml::Generator::create(); + auto profile = libcellml::GeneratorProfile::create(); + + profile->setImplementationVersionString("const char VERSION[] = \".\";\n"); + + generator->implementationCode(analyserModel, profile); + + profile->setImplementationVersionString("const char VERSION[] = \"0.0.0.0\";\n"); + + generator->implementationCode(analyserModel, profile); + + profile->setImplementationVersionString("const char VERSION[] = \"0.0.0"); + + generator->implementationCode(analyserModel, profile); +} + TEST(Coverage, generatorWithNoTracking) { auto parser = libcellml::Parser::create(); @@ -1156,3 +1181,17 @@ TEST(CoverageModelFlattening, componentWithMathThatIsNotMathML) auto flattenedModel = importer->flattenModel(model); EXPECT_EQ(size_t(1), flattenedModel->unitsCount()); } + +TEST(PrinterCoverage, printMath) +{ + auto model = libcellml::Model::create("model"); + auto component = libcellml::Component::create("component"); + + model->addComponent(component); + + auto printer = libcellml::Printer::create(); + + component->setMath("printModel(model); +} diff --git a/tests/generator/generator.cpp b/tests/generator/generator.cpp index 069c6bfbb..1172bf17a 100644 --- a/tests/generator/generator.cpp +++ b/tests/generator/generator.cpp @@ -1767,14 +1767,14 @@ TEST(Generator, veryBigModelMultipleTimes) ++issueCount; - fingerprint += std::to_string(static_cast(issue->level())) + "|"; - fingerprint += std::to_string(static_cast(issue->referenceRule())) + "|"; - fingerprint += std::to_string(static_cast(issue->item()->type())) + "|"; + fingerprint += std::format("{}", static_cast(issue->level())) + "|"; + fingerprint += std::format("{}", static_cast(issue->referenceRule())) + "|"; + fingerprint += std::format("{}", static_cast(issue->item()->type())) + "|"; fingerprint += issue->url() + "|"; fingerprint += issue->description() + "\n"; } - return "issues=" + std::to_string(issueCount) + "\n" + fingerprint; + return "issues=" + std::format("{}", issueCount) + "\n" + fingerprint; }; auto veryBigModel = fileContents("very_big_model.cellml"); From 03e09a8c6a430c1e698a59f117eb60d942969a71 Mon Sep 17 00:00:00 2001 From: Alan Garny Date: Sat, 18 Apr 2026 15:33:11 +1200 Subject: [PATCH 06/12] Improvements to the overall speed and memory use of libCellML. --- src/analyser.cpp | 24 ------------------- src/analyser_p.h | 4 ---- src/model.cpp | 6 ++--- src/printer.cpp | 15 +++++++----- src/utilities.cpp | 12 +++++----- tests/printer/printer.cpp | 49 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 67 insertions(+), 43 deletions(-) diff --git a/src/analyser.cpp b/src/analyser.cpp index dfa136f3c..cc5c8be04 100644 --- a/src/analyser.cpp +++ b/src/analyser.cpp @@ -983,30 +983,6 @@ void Analyser::AnalyserImpl::analyseComponentVariables(const ComponentPtr &compo } } -void Analyser::AnalyserImpl::equivalentVariables(const VariablePtr &variable, VariablePtrs &equivVariables, - std::unordered_set &seen) const -{ - for (size_t i = 0; i < variable->equivalentVariableCount(); ++i) { - auto equivVariable = variable->equivalentVariable(i); - - if (seen.insert(equivVariable.get()).second) { - equivVariables.push_back(equivVariable); - - equivalentVariables(equivVariable, equivVariables, seen); - } - } -} - -VariablePtrs Analyser::AnalyserImpl::equivalentVariables(const VariablePtr &variable) const -{ - VariablePtrs res = {variable}; - std::unordered_set seen = {variable.get()}; - - equivalentVariables(variable, res, seen); - - return res; -} - void Analyser::AnalyserImpl::analyseEquationAst(const AnalyserEquationAstPtr &ast) { // Make sure that we have an AST to analyse. diff --git a/src/analyser_p.h b/src/analyser_p.h index 515c2745c..d6b31f49f 100644 --- a/src/analyser_p.h +++ b/src/analyser_p.h @@ -187,10 +187,6 @@ class Analyser::AnalyserImpl: public Logger::LoggerImpl void analyseComponent(const ComponentPtr &component); void analyseComponentVariables(const ComponentPtr &component); - void equivalentVariables(const VariablePtr &variable, VariablePtrs &equivalentVariables, - std::unordered_set &seen) const; - VariablePtrs equivalentVariables(const VariablePtr &variable) const; - void analyseEquationAst(const AnalyserEquationAstPtr &ast); void updateUnitsMapWithStandardUnit(const std::string &unitsName, diff --git a/src/model.cpp b/src/model.cpp index 3ff83def3..36bf6b196 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -462,20 +462,20 @@ bool Model::doEquals(const EntityPtr &other) const std::vector Model::importRequirements() const { std::vector requirements; - std::unordered_set seen; + std::unordered_set seenUrls; auto importedComponents = getImportedComponents(shared_from_this()); auto importedUnits = getImportedUnits(shared_from_this()); for (auto &component : importedComponents) { auto url = component->importSource()->url(); - if (seen.insert(url).second) { + if (seenUrls.insert(url).second) { requirements.push_back(url); } } for (auto &units : importedUnits) { auto url = units->importSource()->url(); - if (seen.insert(url).second) { + if (seenUrls.insert(url).second) { requirements.push_back(url); } } diff --git a/src/printer.cpp b/src/printer.cpp index 7cda04068..59559c3bd 100644 --- a/src/printer.cpp +++ b/src/printer.cpp @@ -130,16 +130,19 @@ std::string Printer::PrinterImpl::printMath(const std::string &math) XmlDocPtr xmlDoc = std::make_shared(); xmlKeepBlanksDefault(0); - // Remove any XML declarations from the string. + // Remove a leading XML declaration from the string, but preserve other processing instructions such as + // . std::string normalisedMath = math; size_t pos = 0; while ((pos = normalisedMath.find("", pos + 5); - if (end != std::string::npos) { - normalisedMath.erase(pos, end + 2 - pos); - } else { - break; + if ((pos + 5 < normalisedMath.size()) && std::isspace(static_cast(normalisedMath[pos + 5]))) { + auto end = normalisedMath.find("?>", pos + 5); + if (end != std::string::npos) { + normalisedMath.erase(pos, end + 2 - pos); + continue; + } } + pos += 5; } xmlDoc->parse("<" + wrapElementName + ">" + normalisedMath + ""); if (xmlDoc->xmlErrorCount() == 0) { diff --git a/src/utilities.cpp b/src/utilities.cpp index f51eba4a5..8daa5255b 100644 --- a/src/utilities.cpp +++ b/src/utilities.cpp @@ -1034,25 +1034,25 @@ ConnectionMap createConnectionMap(const VariablePtr &variable1, const VariablePt return map; } -void recursiveEquivalentVariables(const VariablePtr &variable, std::vector &equivalentVariables, std::unordered_set &seen) +void recursiveEquivalentVariables(const VariablePtr &variable, std::vector &equivalentVariables, std::unordered_set &seenVariables) { for (size_t i = 0; i < variable->equivalentVariableCount(); ++i) { VariablePtr equivalentVariable = variable->equivalentVariable(i); - if (seen.insert(equivalentVariable.get()).second) { + if (seenVariables.insert(equivalentVariable.get()).second) { equivalentVariables.push_back(equivalentVariable); - recursiveEquivalentVariables(equivalentVariable, equivalentVariables, seen); + recursiveEquivalentVariables(equivalentVariable, equivalentVariables, seenVariables); } } } std::vector equivalentVariables(const VariablePtr &variable) { - std::vector res = {variable}; - std::unordered_set seen = {variable.get()}; + VariablePtrs res = {variable}; + std::unordered_set seenVariables = {variable.get()}; - recursiveEquivalentVariables(variable, res, seen); + recursiveEquivalentVariables(variable, res, seenVariables); return res; } diff --git a/tests/printer/printer.cpp b/tests/printer/printer.cpp index 74692e53d..5b30d99da 100644 --- a/tests/printer/printer.cpp +++ b/tests/printer/printer.cpp @@ -1038,3 +1038,52 @@ TEST(Printer, printComponentWithMultipleFullyQualifiedMathDocuments) const std::string e = fileContents("printer/component_with_multiple_math.cellml"); EXPECT_EQ(e, printer->printModel(model)); } + +TEST(Printer, printComponentWithXmlStylesheetProcessingInstructionInMath) +{ + auto printer = libcellml::Printer::create(); + auto model = libcellml::Model::create("model"); + auto component = libcellml::Component::create("environment"); + const std::string math = + "\n" + "\n" + " \n" + " \n" + " x\n" + " 1\n" + " \n" + "\n"; + + model->addComponent(component); + component->setMath(math); + + auto output = printer->printModel(model); + + EXPECT_EQ(size_t(0), printer->issueCount()); + EXPECT_NE(std::string::npos, output.find("x")); +} + +TEST(Printer, printComponentWithMalformedXmlDeclarationInMath) +{ + auto printer = libcellml::Printer::create(); + auto model = libcellml::Model::create("model"); + auto component = libcellml::Component::create("environment"); + const std::string math = + "\n" + " \n" + " \n" + " x\n" + " 1\n" + " \n" + "\n"; + + model->addComponent(component); + component->setMath(math); + + auto output = printer->printModel(model); + + EXPECT_GT(printer->issueCount(), size_t(0)); + EXPECT_EQ(std::string::npos, output.find(" Date: Tue, 21 Apr 2026 09:40:54 +1200 Subject: [PATCH 07/12] Removed some TODOs and inline comments from our very bid model. --- tests/resources/very_big_model.cellml | 62 +-------------------------- 1 file changed, 1 insertion(+), 61 deletions(-) diff --git a/tests/resources/very_big_model.cellml b/tests/resources/very_big_model.cellml index 517eb82f4..602013d63 100644 --- a/tests/resources/very_big_model.cellml +++ b/tests/resources/very_big_model.cellml @@ -2253,8 +2253,7 @@ T - + t_astart_norm @@ -2264,8 +2263,6 @@ T - t_vstart_norm @@ -2275,8 +2272,6 @@ T - e_a @@ -28986,7 +28981,6 @@ - @@ -29143,7 +29137,6 @@ - @@ -29300,7 +29293,6 @@ - @@ -29457,7 +29449,6 @@ - @@ -29614,7 +29605,6 @@ - @@ -29771,7 +29761,6 @@ - @@ -29928,7 +29917,6 @@ - @@ -30085,7 +30073,6 @@ - @@ -30242,7 +30229,6 @@ - @@ -30399,7 +30385,6 @@ - @@ -30556,7 +30541,6 @@ - @@ -30713,7 +30697,6 @@ - @@ -30870,7 +30853,6 @@ - @@ -31027,7 +31009,6 @@ - @@ -31184,7 +31165,6 @@ - @@ -31341,7 +31321,6 @@ - @@ -31498,7 +31477,6 @@ - @@ -31655,7 +31633,6 @@ - @@ -31812,7 +31789,6 @@ - @@ -31969,7 +31945,6 @@ - @@ -32126,7 +32101,6 @@ - @@ -32285,7 +32259,6 @@ 1-6 - @@ -32314,7 +32287,6 @@ C_T - u @@ -32429,7 +32401,6 @@ 1-6 - @@ -32458,7 +32429,6 @@ C_T - u @@ -32573,7 +32543,6 @@ 1-6 - @@ -32602,7 +32571,6 @@ C_T - u @@ -32717,7 +32685,6 @@ 1-6 - @@ -32746,7 +32713,6 @@ C_T - u @@ -32861,7 +32827,6 @@ 1-6 - @@ -32890,7 +32855,6 @@ C_T - u @@ -33005,7 +32969,6 @@ 1-6 - @@ -33034,7 +32997,6 @@ C_T - u @@ -33149,7 +33111,6 @@ 1-6 - @@ -33178,7 +33139,6 @@ C_T - u @@ -33293,7 +33253,6 @@ 1-6 - @@ -33322,7 +33281,6 @@ C_T - u @@ -33437,7 +33395,6 @@ 1-6 - @@ -33466,7 +33423,6 @@ C_T - u @@ -33581,7 +33537,6 @@ 1-6 - @@ -33610,7 +33565,6 @@ C_T - u @@ -33725,7 +33679,6 @@ 1-6 - @@ -33754,7 +33707,6 @@ C_T - u @@ -33869,7 +33821,6 @@ 1-6 - @@ -33898,7 +33849,6 @@ C_T - u @@ -34013,7 +33963,6 @@ 1-6 - @@ -34042,7 +33991,6 @@ C_T - u @@ -34157,7 +34105,6 @@ 1-6 - @@ -34186,7 +34133,6 @@ C_T - u @@ -34343,7 +34289,6 @@ v - q_C @@ -34498,7 +34443,6 @@ v - q_C @@ -34653,7 +34597,6 @@ v - q_C @@ -34808,7 +34751,6 @@ v - q_C @@ -35093,7 +35035,6 @@ - f_s @@ -35471,7 +35412,6 @@ f_v - From 2d09d4599f04d227a0c28a4db9af6b3df278c7ae Mon Sep 17 00:00:00 2001 From: Alan Garny Date: Tue, 21 Apr 2026 13:23:13 +1200 Subject: [PATCH 08/12] Some (very) minor improvement. --- src/analyser.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/analyser.cpp b/src/analyser.cpp index cc5c8be04..5a38126e7 100644 --- a/src/analyser.cpp +++ b/src/analyser.cpp @@ -1525,13 +1525,11 @@ double Analyser::AnalyserImpl::powerValue(const AnalyserEquationAstPtr &ast, return std::log(lhs); case AnalyserEquationAst::Type::LOG: if (ast->mPimpl->mOwnedLeftChild->type() == AnalyserEquationAst::Type::LOGBASE) { - auto logBase = lhs; - - if (areNearlyEqual(logBase, 10.0)) { + if (areNearlyEqual(lhs, 10.0)) { return std::log10(rhs); } - return std::log(rhs) / std::log(logBase); + return std::log(rhs) / std::log(lhs); } return std::log10(lhs); From 818c1af633e4021b73217a61717684d77da80703 Mon Sep 17 00:00:00 2001 From: Alan Garny Date: Wed, 22 Apr 2026 14:33:33 +1200 Subject: [PATCH 09/12] Analyser model: replaced a logical and with a bitwise and. In debug mode (what we use for our coverage tests), `A & B` will get both `A` and `B` to be evaluated even if `A` is `false`. This means that we get 100% branch coverage. In release mode, `A & B` will only evaluate `B` if and only if `A` is `true`, which is the kind of optimisation we are after. --- src/CMakeLists.txt | 4 ---- src/analysermodel_p.h | 11 +---------- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f9956e386..466fb2930 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -303,10 +303,6 @@ if(LIBCELLML_LLVM_COVERAGE) append_target_property(cellml LINK_FLAGS "-fprofile-instr-generate") endif() -if(LIBCELLML_COVERAGE OR LIBCELLML_LLVM_COVERAGE) - target_compile_definitions(cellml PRIVATE CODE_COVERAGE_ENABLED) -endif() - install(TARGETS cellml EXPORT libcellml-targets COMPONENT runtime RUNTIME DESTINATION bin diff --git a/src/analysermodel_p.h b/src/analysermodel_p.h index 5c557b88a..d473ffab2 100644 --- a/src/analysermodel_p.h +++ b/src/analysermodel_p.h @@ -53,16 +53,7 @@ struct AnalyserModel::AnalyserModelImpl bool operator==(const VariableKeyPair &other) const { -#ifdef CODE_COVERAGE_ENABLED - // Use a branchless form so coverage does not depend on short-circuit behaviour. - - const auto firstEqual = static_cast(first == other.first); - const auto secondEqual = static_cast(second == other.second); - - return firstEqual * secondEqual != 0; -#else - return first == other.first && second == other.second; -#endif + return (first == other.first) & (second == other.second); } }; From dbd57c4fec98ae3be2b8adb31f2fd246a99ff4b9 Mon Sep 17 00:00:00 2001 From: Alan Garny Date: Thu, 9 Apr 2026 10:51:31 +1200 Subject: [PATCH 10/12] Generator: use the analyser model's areEquivalentVariables() method. ... rather than the generic areEquivalentVariables() method which doesn't include caching. --- src/generator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/generator.cpp b/src/generator.cpp index 20cc41e81..be3bd6096 100644 --- a/src/generator.cpp +++ b/src/generator.cpp @@ -1945,7 +1945,7 @@ std::string Generator::GeneratorImpl::generateInitialiseVariableCode(const Analy || (generatedConstantDependencies != nullptr)) { auto initialisingAnalyserVariable = std::find_if(remainingVariables.begin(), remainingVariables.end(), [&](const AnalyserVariablePtr &av) { - return areEquivalentVariables(initialValueVariable, av->variable()); + return mAnalyserModel->areEquivalentVariables(initialValueVariable, av->variable()); }); if (initialisingAnalyserVariable != remainingVariables.end()) { From a2672d60999a4247eeefbab3abc4b5c102bcfb08 Mon Sep 17 00:00:00 2001 From: Alan Garny Date: Thu, 9 Apr 2026 01:55:10 +1200 Subject: [PATCH 11/12] AnalyserModel: improved and fixed areEquivalentVariables(). Indeed, in our WebAssembly module, the key was 32-bit (while 64-bit in C++/Python) which caused collisions and incorrect cache hits. So, we replaced the Cantor-pairing key and std::map-based cache with a typed VariableKeyPair and std::unordered_map. This makes the cached-equivalence lookup more explicit, portable, and efficient. --- src/analysermodel.cpp | 19 +++++++------------ src/analysermodel_p.h | 32 +++++++++++++++++++++++++++++--- 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/src/analysermodel.cpp b/src/analysermodel.cpp index 74dbb1f71..fe6c16ca7 100644 --- a/src/analysermodel.cpp +++ b/src/analysermodel.cpp @@ -496,25 +496,20 @@ bool AnalyserModel::areEquivalentVariables(const VariablePtr &variable1, // an AnalyserModel object refers to a static version of a model, which // means that we can safely cache the result of a call to that utility. In // turn, this means that we can speed up any feature (e.g., code generation) - // that also relies on that utility. When it comes to the key for the cache, - // we use the Cantor pairing function with the address of the two variables - // as parameters, thus ensuring the uniqueness of the key (see - // https://en.wikipedia.org/wiki/Pairing_function#Cantor_pairing_function). + // that also relies on that utility. auto v1 = reinterpret_cast(variable1.get()); auto v2 = reinterpret_cast(variable2.get()); - if (v2 < v1) { - v1 += v2; - v2 = v1 - v2; - v1 = v1 - v2; + if (v1 > v2) { + std::swap(v1, v2); } - auto key = ((v1 + v2) * (v1 + v2 + 1) >> 1U) + v2; - auto cacheKey = mPimpl->mCachedEquivalentVariables.find(key); + auto key = AnalyserModel::AnalyserModelImpl::VariableKeyPair {v1, v2}; + auto it = mPimpl->mCachedEquivalentVariables.find(key); - if (cacheKey != mPimpl->mCachedEquivalentVariables.end()) { - return cacheKey->second; + if (it != mPimpl->mCachedEquivalentVariables.end()) { + return it->second; } auto res = libcellml::areEquivalentVariables(variable1, variable2); diff --git a/src/analysermodel_p.h b/src/analysermodel_p.h index 41d3f5e9f..d473ffab2 100644 --- a/src/analysermodel_p.h +++ b/src/analysermodel_p.h @@ -16,7 +16,8 @@ limitations under the License. #pragma once -#include +#include +#include #include "libcellml/analysermodel.h" @@ -45,6 +46,33 @@ struct AnalyserModel::AnalyserModelImpl std::vector mAnalyserEquations; + struct VariableKeyPair + { + uintptr_t first; + uintptr_t second; + + bool operator==(const VariableKeyPair &other) const + { + return (first == other.first) & (second == other.second); + } + }; + + struct VariableKeyPairHash + { + size_t operator()(const VariableKeyPair &pair) const + { + // A simple and portable hash function for a pair of pointers. + + size_t hash = pair.first; + + hash ^= pair.second + 0x9e3779b9 + (hash << 6) + (hash >> 2); + + return hash; + } + }; + + std::unordered_map mCachedEquivalentVariables; + bool mNeedEqFunction = false; bool mNeedNeqFunction = false; bool mNeedLtFunction = false; @@ -72,8 +100,6 @@ struct AnalyserModel::AnalyserModelImpl bool mNeedAcschFunction = false; bool mNeedAcothFunction = false; - std::map mCachedEquivalentVariables; - static AnalyserModelPtr create(const ModelPtr &model = nullptr); AnalyserModelImpl(const ModelPtr &model); From 3e3da6be382c92c0fbf9fa09258e98233dcad3ee Mon Sep 17 00:00:00 2001 From: Alan Garny Date: Fri, 24 Apr 2026 21:29:26 +1200 Subject: [PATCH 12/12] Removed our very big CellML file. --- tests/bindings/javascript/generator.test.js | 87 - tests/bindings/python/test_generator.py | 74 - tests/generator/generator.cpp | 73 - tests/resources/very_big_model.cellml | 43440 ------------------ 4 files changed, 43674 deletions(-) delete mode 100644 tests/resources/very_big_model.cellml diff --git a/tests/bindings/javascript/generator.test.js b/tests/bindings/javascript/generator.test.js index 9ab593532..2c328e6ff 100644 --- a/tests/bindings/javascript/generator.test.js +++ b/tests/bindings/javascript/generator.test.js @@ -83,91 +83,4 @@ describe("Generator tests", () => { const equation_line_2 = libcellml.Generator.equationCodeByProfile(a.analyserModel().analyserEquation(0).ast(), gp) expect(equation_line_2.length).toBe(14) }) - /* - test('Very big model multiple times', () => { - const fs = require('fs') - const path = require('path') - - const issueFingerprint = (logger) => { - let fingerprint = '' - let issueCount = 0 - - const count = logger.issueCount() - for (let i = 0; i < count; ++i) { - const issue = logger.issue(i) - - ++issueCount - - fingerprint += `${issue.level()}|` - fingerprint += `${issue.referenceRule()}|` - fingerprint += `${issue.item().type()}|` - fingerprint += `${issue.url()}|` - fingerprint += `${issue.description()}\n` - } - - return `issues=${issueCount}\n${fingerprint}` - } - - const veryBigModel = fs.readFileSync(path.resolve(__dirname, "../../../../tests/resources/very_big_model.cellml"), "utf8") - - const parser = new libcellml.Parser(false) - const printer = new libcellml.Printer() - const analyser = new libcellml.Analyser() - const generator = new libcellml.Generator() - - let baselineParserFingerprint = '' - let baselinePrintedModel = '' - let baselineAnalyserFingerprint = '' - let baselineAnalyserModelType = libcellml.AnalyserModel.Type.UNKNOWN - let baselineInterfaceCode = '' - let baselineImplementationCode = '' - - for (let i = 0; i < 10; ++i) { - const model = parser.parseModel(veryBigModel) - - expect(model).not.toBeNull() - - const parserFingerprint = issueFingerprint(parser) - const printedModel = printer.printModel(model) - - analyser.analyseModel(model) - - const analyserFingerprint = issueFingerprint(analyser) - const analyserModel = analyser.analyserModel() - - expect(analyserModel).not.toBeNull() - - const interfaceCode = generator.interfaceCode(analyserModel) - const implementationCode = generator.implementationCode(analyserModel) - - if (i === 0) { - baselineParserFingerprint = parserFingerprint - baselinePrintedModel = printedModel - baselineAnalyserFingerprint = analyserFingerprint - baselineAnalyserModelType = analyserModel.type() - baselineInterfaceCode = interfaceCode - baselineImplementationCode = implementationCode - } else { - expect(parserFingerprint).toBe(baselineParserFingerprint) - expect(printedModel).toBe(baselinePrintedModel) - expect(analyserFingerprint).toBe(baselineAnalyserFingerprint) - expect(analyserModel.type()).toBe(baselineAnalyserModelType) - expect(interfaceCode).toBe(baselineInterfaceCode) - expect(implementationCode).toBe(baselineImplementationCode) - } - - // Clean up the model and analyser model before the next iteration. Indeed, if we don't do this, then we end - // up with 10 models and 10 analyser models in memory at the same time, which causes the test to run out of - // memory. - - analyserModel.delete() - model.delete() - } - - generator.delete() - analyser.delete() - printer.delete() - parser.delete() - }) - */ }) diff --git a/tests/bindings/python/test_generator.py b/tests/bindings/python/test_generator.py index 37d691835..e0aca348d 100644 --- a/tests/bindings/python/test_generator.py +++ b/tests/bindings/python/test_generator.py @@ -52,80 +52,6 @@ def test_algebraic_eqn_computed_var_on_rhs(self): self.assertEqual("x = a", Generator.equationCode(am.analyserEquation(0).ast())) self.assertEqual("x = a", Generator_equationCode(am.analyserEquation(0).ast())) - """ - def test_very_big_model_multiple_times(self): - from libcellml import Analyser - from libcellml import AnalyserModel - from libcellml import Generator - from libcellml import Parser - from libcellml import Printer - from test_resources import file_contents - - def issue_fingerprint(logger): - fingerprint = '' - issue_count = 0 - - for i in range(logger.issueCount()): - issue = logger.issue(i) - - issue_count += 1 - - fingerprint += f"{issue.level()}|" - fingerprint += f"{issue.referenceRule()}|" - fingerprint += f"{issue.item().type()}|" - fingerprint += f"{issue.url()}|" - fingerprint += f"{issue.description()}\n" - - return f"issues={issue_count}\n{fingerprint}" - - very_big_model = file_contents('very_big_model.cellml') - - parser = Parser(False) - printer = Printer() - analyser = Analyser() - generator = Generator() - - baseline_parser_fingerprint = '' - baseline_printed_model = '' - baseline_analyser_fingerprint = '' - baseline_analyser_model_type = AnalyserModel.Type.UNKNOWN - baseline_interface_code = '' - baseline_implementation_code = '' - - for i in range(10): - model = parser.parseModel(very_big_model) - - self.assertIsNotNone(model) - - parser_fingerprint = issue_fingerprint(parser) - printed_model = printer.printModel(model) - - analyser.analyseModel(model) - - analyser_fingerprint = issue_fingerprint(analyser) - analyser_model = analyser.analyserModel() - - self.assertIsNotNone(analyser_model) - - interface_code = generator.interfaceCode(analyser_model) - implementation_code = generator.implementationCode(analyser_model) - - if i == 0: - baseline_parser_fingerprint = parser_fingerprint - baseline_printed_model = printed_model - baseline_analyser_fingerprint = analyser_fingerprint - baseline_analyser_model_type = analyser_model.type() - baseline_interface_code = interface_code - baseline_implementation_code = implementation_code - else: - self.assertEqual(baseline_parser_fingerprint, parser_fingerprint) - self.assertEqual(baseline_printed_model, printed_model) - self.assertEqual(baseline_analyser_fingerprint, analyser_fingerprint) - self.assertEqual(baseline_analyser_model_type, analyser_model.type()) - self.assertEqual(baseline_interface_code, interface_code) - self.assertEqual(baseline_implementation_code, implementation_code) - """ - if __name__ == '__main__': unittest.main() diff --git a/tests/generator/generator.cpp b/tests/generator/generator.cpp index 1172bf17a..411080c52 100644 --- a/tests/generator/generator.cpp +++ b/tests/generator/generator.cpp @@ -1754,76 +1754,3 @@ TEST(Generator, generateCodeUsingProfileEnum) EXPECT_EQ_FILE_CONTENTS("generator/algebraic_eqn_computed_var_on_rhs/model.py", generator->implementationCode(analyserModel, libcellml::GeneratorProfile::Profile::PYTHON)); } - -/* -TEST(Generator, veryBigModelMultipleTimes) -{ - auto issueFingerprint = [](const libcellml::LoggerPtr &logger) { - std::string fingerprint; - size_t issueCount = 0; - - for (size_t i = 0; i < logger->issueCount(); ++i) { - const auto issue = logger->issue(i); - - ++issueCount; - - fingerprint += std::format("{}", static_cast(issue->level())) + "|"; - fingerprint += std::format("{}", static_cast(issue->referenceRule())) + "|"; - fingerprint += std::format("{}", static_cast(issue->item()->type())) + "|"; - fingerprint += issue->url() + "|"; - fingerprint += issue->description() + "\n"; - } - - return "issues=" + std::format("{}", issueCount) + "\n" + fingerprint; - }; - - auto veryBigModel = fileContents("very_big_model.cellml"); - - auto parser = libcellml::Parser::create(false); - auto printer = libcellml::Printer::create(); - auto analyser = libcellml::Analyser::create(); - auto generator = libcellml::Generator::create(); - - std::string baselineParserFingerprint; - std::string baselinePrintedModel; - std::string baselineAnalyserFingerprint; - auto baselineAnalyserModelType = libcellml::AnalyserModel::Type::UNKNOWN; - std::string baselineInterfaceCode; - std::string baselineImplementationCode; - - for (size_t i = 0; i < 10; ++i) { - auto model = parser->parseModel(veryBigModel); - - ASSERT_NE(nullptr, model); - - const auto parserFingerprint = issueFingerprint(parser); - const auto printedModel = printer->printModel(model); - - analyser->analyseModel(model); - - const auto analyserFingerprint = issueFingerprint(analyser); - const auto analyserModel = analyser->analyserModel(); - - ASSERT_NE(nullptr, analyserModel); - - const auto interfaceCode = generator->interfaceCode(analyserModel); - const auto implementationCode = generator->implementationCode(analyserModel); - - if (i == 0) { - baselineParserFingerprint = parserFingerprint; - baselinePrintedModel = printedModel; - baselineAnalyserFingerprint = analyserFingerprint; - baselineAnalyserModelType = analyserModel->type(); - baselineInterfaceCode = interfaceCode; - baselineImplementationCode = implementationCode; - } else { - EXPECT_EQ(baselineParserFingerprint, parserFingerprint); - EXPECT_EQ(baselinePrintedModel, printedModel); - EXPECT_EQ(baselineAnalyserFingerprint, analyserFingerprint); - EXPECT_EQ(baselineAnalyserModelType, analyserModel->type()); - EXPECT_EQ(baselineInterfaceCode, interfaceCode); - EXPECT_EQ(baselineImplementationCode, implementationCode); - } - } -} -*/ diff --git a/tests/resources/very_big_model.cellml b/tests/resources/very_big_model.cellml deleted file mode 100644 index 602013d63..000000000 --- a/tests/resources/very_big_model.cellml +++ /dev/null @@ -1,43440 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - chi_afloor - - - chi_a - - - chi_a - - - - - - - - - t - - chi_a - - - - - - 0.25 - T_ac_wCont - - - - - - mt - t_astart_norm - - - - mt - - - t_astart_norm - eps_1 - - - - - chi_afloor - 0.25 - - - - - - - 0.25 - T_ac_wCont - - - - - - - - t_astart_norm - eps_1 - - 1.0 - - - - mt - - - - - t_astart_norm - eps_1 - - 1.0 - - - - - chi_afloor - 0.25 - - - - - - - 0.25 - T_ac_wCont - - - - - - chi_afloor - eps_2 - - - - chi_afloor - 0.25 - - - - - - - 0.25 - T_ar_wCont - - - - - - chi_afloor - 0.25 - - - - chi_afloor - 0.5 - - - - - - - 0.5 - - - - - T_wCont - T_ac_wCont - - T_ar_wCont - - - - - chi_afloor - 0.5 - - - - 0.0 - - - - - - chi_afloor_final - - - - - chi_afloor - 2 - - - - chi_afloor - 0.5 - - - - 0.0 - - - - - - - - chi_vfloor - - - chi_v - - - chi_v - - - - - - - - - t - - chi_v - - - - - - 0.25 - T_vc_wCont - - - - - - mt - t_vstart_norm - - - - mt - - - t_vstart_norm - eps_1 - - - - - chi_vfloor - 0.25 - - - - - - - 0.25 - T_vc_wCont - - - - - - - - t_vstart_norm - eps_1 - - 1.0 - - - - mt - - - - - t_vstart_norm - eps_1 - - 1.0 - - - - - chi_vfloor - 0.25 - - - - - - - 0.25 - T_vc_wCont - - - - - - chi_vfloor - eps_2 - - - - chi_vfloor - 0.25 - - - - - - - 0.25 - T_vr_wCont - - - - - - chi_vfloor - 0.25 - - - - chi_vfloor - 0.5 - - - - - - - 0.5 - - - - - T_wCont - T_vc_wCont - - T_vr_wCont - - - - - chi_vfloor - 0.5 - - - - 0.0 - - - - - - chi_vfloor_final - - - - - chi_vfloor - 2 - - - - chi_vfloor - 0.5 - - - - 0.0 - - - - - - - - - t - - s - - - - 1 - T_wCont - - - - - mt - - - s - - - s - - - - - - - - T_wCont - - - - - T - Delta_T - - T_min - - - - - T_ac_wCont - - - - - T_ac - T_wCont - - T - - - - - T_ar_wCont - - - - - T_ar - T_wCont - - T - - - - - T_vc_wCont - - - - - T_vc - T_wCont - - T - - - - - T_vr_wCont - - - - - T_vr - T_wCont - - T - - - - - - t_astart_norm - - - t_astart - T - - - - - t_vstart_norm - - - t_vstart - T - - - - - e_a - - - 0.5 - - - 1 - - - - - 2 - - chi_afloor_final - - - - - - - - e_v - - - 0.5 - - - 1 - - - - - 2 - - chi_vfloor_final - - - - - - - - - B_trv - - - rho - - - - - 2 - - - A_eff_trv - 2 - - - eps_m4 - - - - - - B_puv - - - rho - - - - - 2 - - - A_eff_puv - 2 - - - eps_m4 - - - - - - B_miv - - - rho - - - - - 2 - - - A_eff_miv - 2 - - - eps_m4 - - - - - - B_aov - - - rho - - - - - 2 - - - A_eff_aov - 2 - - - eps_m4 - - - - - - L_trv - - - - - rho - l_eff - - - - A_eff_trv - eps_m2 - - - - - - L_puv - - - - - rho - l_eff - - - - A_eff_puv - eps_m2 - - - - - - L_miv - - - - - rho - l_eff - - - - A_eff_miv - eps_m2 - - - - - - L_aov - - - - - rho - l_eff - - - - A_eff_aov - eps_m2 - - - - - - A_eff_trv - - - - - - - - - M_st_trv - A_nn_trv - - - - M_rg_trv - A_nn_trv - - - zeta_trv - - - - M_rg_trv - A_nn_trv - - - - - - A_eff_puv - - - - - - - - - M_st_puv - A_nn_puv - - - - M_rg_puv - A_nn_puv - - - zeta_puv - - - - M_rg_puv - A_nn_puv - - - - - - A_eff_miv - - - - - - - - - M_st_miv - A_nn_miv - - - - M_rg_miv - A_nn_miv - - - zeta_miv - - - - M_rg_miv - A_nn_miv - - - - - - A_eff_aov - - - - - - - - - M_st_aov - A_nn_aov - - - - M_rg_aov - A_nn_aov - - - zeta_aov - - - - M_rg_aov - A_nn_aov - - - - - - - - - t - - zeta_trv_pre - - - - - - - - 1 - zeta_trv_pre - - K_vo_trv - - - u_ra - u_rv - - - - - u_ra - u_rv - - - - - - zeta_trv_pre - K_vc_trv - - - u_ra - u_rv - - - - - - - - - - - t - - zeta_puv_pre - - - - - - - - 1 - zeta_puv_pre - - K_vo_puv - - - u_rv - u_par - - - - - u_rv - u_par - - - - - - zeta_puv_pre - K_vc_puv - - - u_rv - u_par - - - - - - - - - - - t - - zeta_miv_pre - - - - - - - - 1 - zeta_miv_pre - - K_vo_miv - - - u_la - u_lv - - - - - u_la - u_lv - - - - - - zeta_miv_pre - K_vc_miv - - - u_la - u_lv - - - - - - - - - - - t - - zeta_aov_pre - - - - - - - - 1 - zeta_aov_pre - - K_vo_aov - - - u_lv - u_root - - - - - u_lv - u_root - - - - - - zeta_aov_pre - K_vc_aov - - - u_lv - u_root - - - - - - - - - zeta_trv - - - zeta_trv_pre - 0 - - - - - zeta_puv - - - zeta_puv_pre - 0 - - - - - zeta_miv - - - zeta_miv_pre - 0 - - - - - zeta_aov - - - zeta_aov_pre - 0 - - - - - - - - - t - - v_trv - - - - - - - - - - - - B_trv - - v_trv - - - v_trv - - - u_ra - - u_rv - - L_trv - - - - - - - - t - - v_puv - - - - - - - - - - - - B_puv - - v_puv - - - v_puv - - - u_rv - - u_par - - L_puv - - - - - - - - t - - v_miv - - - - - - - - - - - - B_miv - - v_miv - - - v_miv - - - u_la - - u_lv - - L_miv - - - - - - - - t - - v_aov - - - - - - - - - - - - B_aov - - v_aov - - - v_aov - - - u_lv - - u_root - - L_aov - - - - - - - E_rv_A_wCont - - - E_rv_A - Delta_E_rv - - - - - E_lv_A_wCont - - - E_lv_A - Delta_E_lv - - - - - - u_ra - - - - - - - e_a - E_ra_A - - E_ra_B - - - - q_ra - q_ra_us - - - - - - u_rv - - - - - - - e_v - E_rv_A_wCont - - E_rv_B - - - - q_rv - q_rv_us - - - - - - u_la - - - - - - - e_a - E_la_A - - E_la_B - - - - q_la - q_la_us - - - - - - u_lv - - - - - - - e_v - E_lv_A_wCont - - E_lv_B - - - - q_lv - q_lv_us - - - - - - - - - - t - - q_ra - - - - - - v_svc - v_ivc - - v_trv - - - - - - - - t - - q_rv - - - - v_trv - v_puv - - - - - - - - t - - q_la - - - - v_pvn - v_miv - - - - - - - - t - - q_lv - - - - v_miv - v_aov - - - - - - - q_heart - - - q_ra - q_rv - q_la - q_lv - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_C_d - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u - u_d - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v_in - v - - - - - u_C - - - q_C - - - C - 2 - - - - - - - - - t - - q_C_d - - - - - - v - v_out_1 - - v_out_2 - - - - - u_C_d - - - q_C_d - - - C - 2 - - - - - - u - - - u_0 - u_C - u_ext - - - 2 - R_v - - - v_in - v - - - - - - - u_d - - - u_0 - u_C_d - u_ext - - - 2 - R_v - - - - - v - v_out_1 - - v_out_2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - du_C_dt - - - - - - - v - v_out_1 - - v_out_2 - - C - - - - - - - - - t - - q_C - - - - - - v - v_out_1 - - v_out_2 - - - - - u_C - - - - - q_C - C - - u_ext - - - - - u - - - u_0 - u_C - - - R_v - - - - - v - v_out_1 - - v_out_2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - du_C_dt - - - - - - - v - v_out_1 - - v_out_2 - - C - - - - - - - - - t - - q_C - - - - - - v - v_out_1 - - v_out_2 - - - - - u_C - - - - - q_C - C - - u_ext - - - - - u - - - u_0 - u_C - - - R_v - - - - - v - v_out_1 - - v_out_2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - du_C_dt - - - - - - - v - v_out_1 - - v_out_2 - - C - - - - - - - - - t - - q_C - - - - - - v - v_out_1 - - v_out_2 - - - - - u_C - - - - - q_C - C - - u_ext - - - - - u - - - u_0 - u_C - - - R_v - - - - - v - v_out_1 - - v_out_2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - du_C_dt - - - - - - - v - v_out_1 - - v_out_2 - - C - - - - - - - - - t - - q_C - - - - - - v - v_out_1 - - v_out_2 - - - - - u_C - - - - - q_C - C - - u_ext - - - - - u - - - u_0 - u_C - - - R_v - - - - - v - v_out_1 - - v_out_2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - du_C_dt - - - - - - - v - v_out_1 - - v_out_2 - - C - - - - - - - - - t - - q_C - - - - - - v - v_out_1 - - v_out_2 - - - - - u_C - - - - - q_C - C - - u_ext - - - - - u - - - u_0 - u_C - - - R_v - - - - - v - v_out_1 - - v_out_2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - du_C_dt - - - - - - - v - v_out_1 - - v_out_2 - - C - - - - - - - - - t - - q_C - - - - - - v - v_out_1 - - v_out_2 - - - - - u_C - - - - - q_C - C - - u_ext - - - - - u - - - u_0 - u_C - - - R_v - - - - - v - v_out_1 - - v_out_2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - du_C_dt - - - - - - - v - v_out_1 - - v_out_2 - - C - - - - - - - - - t - - q_C - - - - - - v - v_out_1 - - v_out_2 - - - - - u_C - - - - - q_C - C - - u_ext - - - - - u - - - u_0 - u_C - - - R_v - - - - - v - v_out_1 - - v_out_2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - du_C_dt - - - - - - - v - v_out_1 - - v_out_2 - - C - - - - - - - - - t - - q_C - - - - - - v - v_out_1 - - v_out_2 - - - - - u_C - - - - - q_C - C - - u_ext - - - - - u - - - u_0 - u_C - - - R_v - - - - - v - v_out_1 - - v_out_2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - du_C_dt - - - - - - - v - v_out_1 - - v_out_2 - - C - - - - - - - - - t - - q_C - - - - - - v - v_out_1 - - v_out_2 - - - - - u_C - - - - - q_C - C - - u_ext - - - - - u - - - u_0 - u_C - - - R_v - - - - - v - v_out_1 - - v_out_2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - du_C_dt - - - - - - - v - v_out_1 - - v_out_2 - - C - - - - - - - - - t - - q_C - - - - - - v - v_out_1 - - v_out_2 - - - - - u_C - - - - - q_C - C - - u_ext - - - - - u - - - u_0 - u_C - - - R_v - - - - - v - v_out_1 - - v_out_2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - du_C_dt - - - - - - - v - v_out_1 - - v_out_2 - - C - - - - - - - - - t - - q_C - - - - - - v - v_out_1 - - v_out_2 - - - - - u_C - - - - - q_C - C - - u_ext - - - - - u - - - u_0 - u_C - - - R_v - - - - - v - v_out_1 - - v_out_2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - du_C_dt - - - - - - - v - v_out_1 - - v_out_2 - - C - - - - - - - - - t - - q_C - - - - - - v - v_out_1 - - v_out_2 - - - - - u_C - - - - - q_C - C - - u_ext - - - - - u - - - u_0 - u_C - - - R_v - - - - - v - v_out_1 - - v_out_2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - du_C_dt - - - - - - - v - v_out_1 - - v_out_2 - - C - - - - - - - - - t - - q_C - - - - - - v - v_out_1 - - v_out_2 - - - - - u_C - - - - - q_C - C - - u_ext - - - - - u - - - u_0 - u_C - - - R_v - - - - - v - v_out_1 - - v_out_2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - du_C_dt - - - - - - - v - v_out_1 - - v_out_2 - - C - - - - - - - - - t - - q_C - - - - - - v - v_out_1 - - v_out_2 - - - - - u_C - - - - - q_C - C - - u_ext - - - - - u - - - u_0 - u_C - - - R_v - - - - - v - v_out_1 - - v_out_2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - du_C_dt - - - - - - - v - v_out_1 - - v_out_2 - - C - - - - - - - - - t - - q_C - - - - - - v - v_out_1 - - v_out_2 - - - - - u_C - - - - - q_C - C - - u_ext - - - - - u - - - u_0 - u_C - - - R_v - - - - - v - v_out_1 - - v_out_2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - du_C_dt - - - - - - - v - v_out_1 - - v_out_2 - - C - - - - - - - - - t - - q_C - - - - - - v - v_out_1 - - v_out_2 - - - - - u_C - - - - - q_C - C - - u_ext - - - - - u - - - u_0 - u_C - - - R_v - - - - - v - v_out_1 - - v_out_2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - du_C_dt - - - - - - - v - v_out_1 - - v_out_2 - - C - - - - - - - - - t - - q_C - - - - - - v - v_out_1 - - v_out_2 - - - - - u_C - - - - - q_C - C - - u_ext - - - - - u - - - u_0 - u_C - - - R_v - - - - - v - v_out_1 - - v_out_2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - du_C_dt - - - - - - - v - v_out_1 - - v_out_2 - - C - - - - - - - - - t - - q_C - - - - - - v - v_out_1 - - v_out_2 - - - - - u_C - - - - - q_C - C - - u_ext - - - - - u - - - u_0 - u_C - - - R_v - - - - - v - v_out_1 - - v_out_2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - du_C_dt - - - - - - - v - v_out_1 - - v_out_2 - - C - - - - - - - - - t - - q_C - - - - - - v - v_out_1 - - v_out_2 - - - - - u_C - - - - - q_C - C - - u_ext - - - - - u - - - u_0 - u_C - - - R_v - - - - - v - v_out_1 - - v_out_2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - du_C_dt - - - - - - - v - v_out_1 - - v_out_2 - - C - - - - - - - - - t - - q_C - - - - - - v - v_out_1 - - v_out_2 - - - - - u_C - - - - - q_C - C - - u_ext - - - - - u - - - u_0 - u_C - - - R_v - - - - - v - v_out_1 - - v_out_2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - du_C_dt - - - - - - - v - v_out_1 - - v_out_2 - - C - - - - - - - - - t - - q_C - - - - - - v - v_out_1 - - v_out_2 - - - - - u_C - - - - - q_C - C - - u_ext - - - - - u - - - u_0 - u_C - - - R_v - - - - - v - v_out_1 - - v_out_2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - du_C_dt - - - - - - - v - v_out_1 - - v_out_2 - - C - - - - - - - - - t - - q_C - - - - - - v - v_out_1 - - v_out_2 - - - - - u_C - - - - - q_C - C - - u_ext - - - - - u - - - u_0 - u_C - - - R_v - - - - - v - v_out_1 - - v_out_2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - du_C_dt - - - - - - - v - v_out_1 - - v_out_2 - - C - - - - - - - - - t - - q_C - - - - - - v - v_out_1 - - v_out_2 - - - - - u_C - - - - - q_C - C - - u_ext - - - - - u - - - u_0 - u_C - - - R_v - - - - - v - v_out_1 - - v_out_2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - du_C_dt - - - - - - - v - v_out_1 - - v_out_2 - - C - - - - - - - - - t - - q_C - - - - - - v - v_out_1 - - v_out_2 - - - - - u_C - - - - - q_C - C - - u_ext - - - - - u - - - u_0 - u_C - - - R_v - - - - - v - v_out_1 - - v_out_2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - du_C_dt - - - - - - - v - v_out_1 - - v_out_2 - - C - - - - - - - - - t - - q_C - - - - - - v - v_out_1 - - v_out_2 - - - - - u_C - - - - - q_C - C - - u_ext - - - - - u - - - u_0 - u_C - - - R_v - - - - - v - v_out_1 - - v_out_2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - du_C_dt - - - - - - - v - v_out_1 - - v_out_2 - - C - - - - - - - - - t - - q_C - - - - - - v - v_out_1 - - v_out_2 - - - - - u_C - - - - - q_C - C - - u_ext - - - - - u - - - u_0 - u_C - - - R_v - - - - - v - v_out_1 - - v_out_2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - du_C_dt - - - - - - - v - v_out_1 - - v_out_2 - - C - - - - - - - - - t - - q_C - - - - - - v - v_out_1 - - v_out_2 - - - - - u_C - - - - - q_C - C - - u_ext - - - - - u - - - u_0 - u_C - - - R_v - - - - - v - v_out_1 - - v_out_2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - - - R - 2 - - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - - - I - 2 - - - - - - - - - t - - q_C - - - - v - v_d - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_d - - - - - - - - - - t - - v_d - - - - - - - - u - u_out - - - - - - R - 2 - - v_d - - - - - I - 2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - - - R - 2 - - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - - - I - 2 - - - - - - - - - t - - q_C - - - - v - v_d - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_d - - - - - - - - - - t - - v_d - - - - - - - - u - u_out - - - - - - R - 2 - - v_d - - - - - I - 2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_C_d - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u - u_d - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - - - v_in_1 - v_in_2 - - v - - - - - u_C - - - q_C - - - C - 2 - - - - - - - - - t - - q_C_d - - - - - - v - v_out_1 - - v_out_2 - - - - - u_C_d - - - q_C_d - - - C - 2 - - - - - - u - - - u_0 - u_ext - u_C - - - 2 - R_v - - - - - v_in_1 - v_in_2 - - v - - - - - - - u_d - - - u_0 - u_ext - u_C_d - - - 2 - R_v - - - - - v - v_out_1 - - v_out_2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - du_C_dt - - - - - - - v - v_out_1 - - v_out_2 - - C - - - - - - - - - t - - q_C - - - - - - v - v_out_1 - - v_out_2 - - - - - u_C - - - - - q_C - C - - u_ext - - - - - u - - - u_0 - u_C - - - R_v - - - - - v - v_out_1 - - v_out_2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - du_C_dt - - - - - - - v - v_out_1 - - v_out_2 - - C - - - - - - - - - t - - q_C - - - - - - v - v_out_1 - - v_out_2 - - - - - u_C - - - - - q_C - C - - u_ext - - - - - u - - - u_0 - u_C - - - R_v - - - - - v - v_out_1 - - v_out_2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - du_C_dt - - - - - - - v - v_out_1 - - v_out_2 - - C - - - - - - - - - t - - q_C - - - - - - v - v_out_1 - - v_out_2 - - - - - u_C - - - - - q_C - C - - u_ext - - - - - u - - - u_0 - u_C - - - R_v - - - - - v - v_out_1 - - v_out_2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - du_C_dt - - - - - - - v - v_out_1 - - v_out_2 - - C - - - - - - - - - t - - q_C - - - - - - v - v_out_1 - - v_out_2 - - - - - u_C - - - - - q_C - C - - u_ext - - - - - u - - - u_0 - u_C - - - R_v - - - - - v - v_out_1 - - v_out_2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - du_C_dt - - - - - - - v - v_out_1 - - v_out_2 - - C - - - - - - - - - t - - q_C - - - - - - v - v_out_1 - - v_out_2 - - - - - u_C - - - - - q_C - C - - u_ext - - - - - u - - - u_0 - u_C - - - R_v - - - - - v - v_out_1 - - v_out_2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - du_C_dt - - - - - - - v - v_out_1 - - v_out_2 - - C - - - - - - - - - t - - q_C - - - - - - v - v_out_1 - - v_out_2 - - - - - u_C - - - - - q_C - C - - u_ext - - - - - u - - - u_0 - u_C - - - R_v - - - - - v - v_out_1 - - v_out_2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - du_C_dt - - - - - - - v - v_out_1 - - v_out_2 - - C - - - - - - - - - t - - q_C - - - - - - v - v_out_1 - - v_out_2 - - - - - u_C - - - - - q_C - C - - u_ext - - - - - u - - - u_0 - u_C - - - R_v - - - - - v - v_out_1 - - v_out_2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - - - R - 2 - - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - - - I - 2 - - - - - - - - - t - - q_C - - - - v - v_d - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_d - - - - - - - - - - t - - v_d - - - - - - - - u - u_out - - - - - - R - 2 - - v_d - - - - - I - 2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - du_C_dt - - - - - - - v - v_out_1 - - v_out_2 - - C - - - - - - - - - t - - q_C - - - - - - v - v_out_1 - - v_out_2 - - - - - u_C - - - - - q_C - C - - u_ext - - - - - u - - - u_0 - u_C - - - R_v - - - - - v - v_out_1 - - v_out_2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - du_C_dt - - - - - - - v - v_out_1 - - v_out_2 - - C - - - - - - - - - t - - q_C - - - - - - v - v_out_1 - - v_out_2 - - - - - u_C - - - - - q_C - C - - u_ext - - - - - u - - - u_0 - u_C - - - R_v - - - - - v - v_out_1 - - v_out_2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - - - R - 2 - - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - - - I - 2 - - - - - - - - - t - - q_C - - - - v - v_d - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_d - - - - - - - - - - t - - v_d - - - - - - - - u - u_out - - - - - - R - 2 - - v_d - - - - - I - 2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u - u_out - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - - - v_in_1 - v_in_2 - - v - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_ext - u_C - - - R_v - - - - - v_in_1 - v_in_2 - - v - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_C_d - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u - u_d - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - - - v_in_1 - v_in_2 - - v - - - - - u_C - - - q_C - - - C - 2 - - - - - - - - - t - - q_C_d - - - - v - v_out - - - - - u_C_d - - - q_C_d - - - C - 2 - - - - - - u - - - u_0 - u_ext - u_C - - - 2 - R_v - - - - - v_in_1 - v_in_2 - - v - - - - - - - u_d - - - u_0 - u_ext - u_C_d - - - 2 - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - - - R - 2 - - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - - - I - 2 - - - - - - - - - t - - q_C - - - - v - v_d - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_d - - - - - - - - - - t - - v_d - - - - - - - - u - u_out - - - - - - R - 2 - - v_d - - - - - I - 2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - - - R - 2 - - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - - - I - 2 - - - - - - - - - t - - q_C - - - - v - v_d - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_d - - - - - - - - - - t - - v_d - - - - - - - - u - u_out - - - - - - R - 2 - - v_d - - - - - I - 2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_C_d - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u - u_d - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - - - v_in_1 - v_in_2 - - v - - - - - u_C - - - q_C - - - C - 2 - - - - - - - - - t - - q_C_d - - - - v - v_out - - - - - u_C_d - - - q_C_d - - - C - 2 - - - - - - u - - - u_0 - u_ext - u_C - - - 2 - R_v - - - - - v_in_1 - v_in_2 - - v - - - - - - - u_d - - - u_0 - u_ext - u_C_d - - - 2 - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - - - R - 2 - - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - - - I - 2 - - - - - - - - - t - - q_C - - - - v - v_d - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_d - - - - - - - - - - t - - v_d - - - - - - - - u - u_out - - - - - - R - 2 - - v_d - - - - - I - 2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - q_0 - - - - - - r_0 - 2 - - l - - - - - q - - - q_C - q_0 - - - - - - h - - - r_0 - - - - - a_vessel - - - - - b_vessel - r_0 - - - - - - c_vessel - - - - - d_vessel - r_0 - - - - - - - - - I - - - - - rho - l - - - - - - - r_0 - 2 - - - - - - - C - - - - - 2 - - - - r_0 - 3 - - l - - - - E - h - - - - - - R - - - - - 8 - mu - l - - - - - - - r_0 - 4 - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - - - u_in - u - - - - R - v - - - - - beta_g - rho - g - l - - - - - - - theta - - - 180 - - - - - I - - - - - - - - t - - q_C - - - - v - v_out - - - - - u_C - - - q_C - C - - - - - u - - - u_0 - u_C - u_ext - - - R_v - - - v - v_out - - - - - - - - - - - - - - - - - - - - - - - - - - - - - R_v - - - 0.01 - C_T - - - - - - - - - t - - q - - - - v - v_T - - - - - u_C - - - - - - - q - q_us - - C_T - - u_ext - - - - - u - - - u_C - - - R_v - - - v - v_T - - - - - - - - - - t - - v - - - - - - - - u_in - u - - - - - - v - R_T_wCont - - 2 - - - I_T - - - - - - - - t - - v_T - - - - - - - - u - u_out - - - - - - v_T - R_T_wCont - - 2 - - - I_T - - - - - R_T_wCont - - - - - R_T - Delta_R - - R_local_multiplier - - - - - - - - - - - - - - - - - - - - - - - - - - - R_v - - - 0.01 - C_T - - - - - - - - - t - - q - - - - v - v_T - - - - - u_C - - - - - - - q - q_us - - C_T - - u_ext - - - - - u - - - u_C - - - R_v - - - v - v_T - - - - - - - - - - t - - v - - - - - - - - u_in - u - - - - - - v - R_T_wCont - - 2 - - - I_T - - - - - - - - t - - v_T - - - - - - - - u - u_out - - - - - - v_T - R_T_wCont - - 2 - - - I_T - - - - - R_T_wCont - - - - - R_T - Delta_R - - R_local_multiplier - - - - - - - - - - - - - - - - - - - - - - - - - - - R_v - - - 0.01 - C_T - - - - - - - - - t - - q - - - - v - v_T - - - - - u_C - - - - - - - q - q_us - - C_T - - u_ext - - - - - u - - - u_C - - - R_v - - - v - v_T - - - - - - - - - - t - - v - - - - - - - - u_in - u - - - - - - v - R_T_wCont - - 2 - - - I_T - - - - - - - - t - - v_T - - - - - - - - u - u_out - - - - - - v_T - R_T_wCont - - 2 - - - I_T - - - - - R_T_wCont - - - - - R_T - Delta_R - - R_local_multiplier - - - - - - - - - - - - - - - - - - - - - - - - - - - R_v - - - 0.01 - C_T - - - - - - - - - t - - q - - - - v - v_T - - - - - u_C - - - - - - - q - q_us - - C_T - - u_ext - - - - - u - - - u_C - - - R_v - - - v - v_T - - - - - - - - - - t - - v - - - - - - - - u_in - u - - - - - - v - R_T_wCont - - 2 - - - I_T - - - - - - - - t - - v_T - - - - - - - - u - u_out - - - - - - v_T - R_T_wCont - - 2 - - - I_T - - - - - R_T_wCont - - - - - R_T - Delta_R - - R_local_multiplier - - - - - - - - - - - - - - - - - - - - - - - - - - - R_v - - - 0.01 - C_T - - - - - - - - - t - - q - - - - v - v_T - - - - - u_C - - - - - - - q - q_us - - C_T - - u_ext - - - - - u - - - u_C - - - R_v - - - v - v_T - - - - - - - - - - t - - v - - - - - - - - u_in - u - - - - - - v - R_T_wCont - - 2 - - - I_T - - - - - - - - t - - v_T - - - - - - - - u - u_out - - - - - - v_T - R_T_wCont - - 2 - - - I_T - - - - - R_T_wCont - - - - - R_T - Delta_R - - R_local_multiplier - - - - - - - - - - - - - - - - - - - - - - - - - - - R_v - - - 0.01 - C_T - - - - - - - - - t - - q - - - - v - v_T - - - - - u_C - - - - - - - q - q_us - - C_T - - u_ext - - - - - u - - - u_C - - - R_v - - - v - v_T - - - - - - - - - - t - - v - - - - - - - - u_in - u - - - - - - v - R_T_wCont - - 2 - - - I_T - - - - - - - - t - - v_T - - - - - - - - u - u_out - - - - - - v_T - R_T_wCont - - 2 - - - I_T - - - - - R_T_wCont - - - - - R_T - Delta_R - - R_local_multiplier - - - - - - - - - - - - - - - - - - - - - - - - - - - R_v - - - 0.01 - C_T - - - - - - - - - t - - q - - - - v - v_T - - - - - u_C - - - - - - - q - q_us - - C_T - - u_ext - - - - - u - - - u_C - - - R_v - - - v - v_T - - - - - - - - - - t - - v - - - - - - - - u_in - u - - - - - - v - R_T_wCont - - 2 - - - I_T - - - - - - - - t - - v_T - - - - - - - - u - u_out - - - - - - v_T - R_T_wCont - - 2 - - - I_T - - - - - R_T_wCont - - - - - R_T - Delta_R - - R_local_multiplier - - - - - - - - - - - - - - - - - - - - - - - - - - - R_v - - - 0.01 - C_T - - - - - - - - - t - - q - - - - v - v_T - - - - - u_C - - - - - - - q - q_us - - C_T - - u_ext - - - - - u - - - u_C - - - R_v - - - v - v_T - - - - - - - - - - t - - v - - - - - - - - u_in - u - - - - - - v - R_T_wCont - - 2 - - - I_T - - - - - - - - t - - v_T - - - - - - - - u - u_out - - - - - - v_T - R_T_wCont - - 2 - - - I_T - - - - - R_T_wCont - - - - - R_T - Delta_R - - R_local_multiplier - - - - - - - - - - - - - - - - - - - - - - - - - - - R_v - - - 0.01 - C_T - - - - - - - - - t - - q - - - - v - v_T - - - - - u_C - - - - - - - q - q_us - - C_T - - u_ext - - - - - u - - - u_C - - - R_v - - - v - v_T - - - - - - - - - - t - - v - - - - - - - - u_in - u - - - - - - v - R_T_wCont - - 2 - - - I_T - - - - - - - - t - - v_T - - - - - - - - u - u_out - - - - - - v_T - R_T_wCont - - 2 - - - I_T - - - - - R_T_wCont - - - - - R_T - Delta_R - - R_local_multiplier - - - - - - - - - - - - - - - - - - - - - - - - - - - R_v - - - 0.01 - C_T - - - - - - - - - t - - q - - - - v - v_T - - - - - u_C - - - - - - - q - q_us - - C_T - - u_ext - - - - - u - - - u_C - - - R_v - - - v - v_T - - - - - - - - - - t - - v - - - - - - - - u_in - u - - - - - - v - R_T_wCont - - 2 - - - I_T - - - - - - - - t - - v_T - - - - - - - - u - u_out - - - - - - v_T - R_T_wCont - - 2 - - - I_T - - - - - R_T_wCont - - - - - R_T - Delta_R - - R_local_multiplier - - - - - - - - - - - - - - - - - - - - - - - - - - - R_v - - - 0.01 - C_T - - - - - - - - - t - - q - - - - v - v_T - - - - - u_C - - - - - - - q - q_us - - C_T - - u_ext - - - - - u - - - u_C - - - R_v - - - v - v_T - - - - - - - - - - t - - v - - - - - - - - u_in - u - - - - - - v - R_T_wCont - - 2 - - - I_T - - - - - - - - t - - v_T - - - - - - - - u - u_out - - - - - - v_T - R_T_wCont - - 2 - - - I_T - - - - - R_T_wCont - - - - - R_T - Delta_R - - R_local_multiplier - - - - - - - - - - - - - - - - - - - - - - - - - - - R_v - - - 0.01 - C_T - - - - - - - - - t - - q - - - - v - v_T - - - - - u_C - - - - - - - q - q_us - - C_T - - u_ext - - - - - u - - - u_C - - - R_v - - - v - v_T - - - - - - - - - - t - - v - - - - - - - - u_in - u - - - - - - v - R_T_wCont - - 2 - - - I_T - - - - - - - - t - - v_T - - - - - - - - u - u_out - - - - - - v_T - R_T_wCont - - 2 - - - I_T - - - - - R_T_wCont - - - - - R_T - Delta_R - - R_local_multiplier - - - - - - - - - - - - - - - - - - - - - - - - - - - R_v - - - 0.01 - C_T - - - - - - - - - t - - q - - - - v - v_T - - - - - u_C - - - - - - - q - q_us - - C_T - - u_ext - - - - - u - - - u_C - - - R_v - - - v - v_T - - - - - - - - - - t - - v - - - - - - - - u_in - u - - - - - - v - R_T_wCont - - 2 - - - I_T - - - - - - - - t - - v_T - - - - - - - - u - u_out - - - - - - v_T - R_T_wCont - - 2 - - - I_T - - - - - R_T_wCont - - - - - R_T - Delta_R - - R_local_multiplier - - - - - - - - - - - - - - - - - - - - - - - - - - - R_v - - - 0.01 - C_T - - - - - - - - - t - - q - - - - v - v_T - - - - - u_C - - - - - - - q - q_us - - C_T - - u_ext - - - - - u - - - u_C - - - R_v - - - v - v_T - - - - - - - - - - t - - v - - - - - - - - u_in - u - - - - - - v - R_T_wCont - - 2 - - - I_T - - - - - - - - t - - v_T - - - - - - - - u - u_out - - - - - - v_T - R_T_wCont - - 2 - - - I_T - - - - - R_T_wCont - - - - - R_T - Delta_R - - R_local_multiplier - - - - - - - - - - - - - - - - - - - - - - - - - - - R_v - - - 0.01 - C_T - - - - - - - - - t - - q - - - - v - v_T - - - - - u_C - - - - - - - q - q_us - - C_T - - u_ext - - - - - u - - - u_C - - - R_v - - - v - v_T - - - - - - - - - - t - - v - - - - - - - - u_in - u - - - - - - v - R_T_wCont - - 2 - - - I_T - - - - - - - - t - - v_T - - - - - - - - u - u_out - - - - - - v_T - R_T_wCont - - 2 - - - I_T - - - - - R_T_wCont - - - - - R_T - Delta_R - - R_local_multiplier - - - - - - - - - - - - - - - - - - - - - - - - - - - R_v - - - 0.01 - C_T - - - - - - - - - t - - q - - - - v - v_T - - - - - u_C - - - - - - - q - q_us - - C_T - - u_ext - - - - - u - - - u_C - - - R_v - - - v - v_T - - - - - - - - - - t - - v - - - - - - - - u_in - u - - - - - - v - R_T_wCont - - 2 - - - I_T - - - - - - - - t - - v_T - - - - - - - - u - u_out - - - - - - v_T - R_T_wCont - - 2 - - - I_T - - - - - R_T_wCont - - - - - R_T - Delta_R - - R_local_multiplier - - - - - - - - - - - - - - - - - - - - - - - - - - - R_v - - - 0.01 - C_T - - - - - - - - - t - - q - - - - v - v_T - - - - - u_C - - - - - - - q - q_us - - C_T - - u_ext - - - - - u - - - u_C - - - R_v - - - v - v_T - - - - - - - - - - t - - v - - - - - - - - u_in - u - - - - - - v - R_T_wCont - - 2 - - - I_T - - - - - - - - t - - v_T - - - - - - - - u - u_out - - - - - - v_T - R_T_wCont - - 2 - - - I_T - - - - - R_T_wCont - - - - - R_T - Delta_R - - R_local_multiplier - - - - - - - - - - - - - - - - - - - - - - - - - - - R_v - - - 0.01 - C_T - - - - - - - - - t - - q - - - - v - v_T - - - - - u_C - - - - - - - q - q_us - - C_T - - u_ext - - - - - u - - - u_C - - - R_v - - - v - v_T - - - - - - - - - - t - - v - - - - - - - - u_in - u - - - - - - v - R_T_wCont - - 2 - - - I_T - - - - - - - - t - - v_T - - - - - - - - u - u_out - - - - - - v_T - R_T_wCont - - 2 - - - I_T - - - - - R_T_wCont - - - - - R_T - Delta_R - - R_local_multiplier - - - - - - - - - - - - - - - - - - - - - - - - - - - R_v - - - 0.01 - C_T - - - - - - - - - t - - q - - - - v - v_T - - - - - u_C - - - - - - - q - q_us - - C_T - - u_ext - - - - - u - - - u_C - - - R_v - - - v - v_T - - - - - - - - - - t - - v - - - - - - - - u_in - u - - - - - - v - R_T_wCont - - 2 - - - I_T - - - - - - - - t - - v_T - - - - - - - - u - u_out - - - - - - v_T - R_T_wCont - - 2 - - - I_T - - - - - R_T_wCont - - - - - R_T - Delta_R - - R_local_multiplier - - - - - - - - - - - - - - - - - - - - - - - - - - - R_v - - - 0.01 - C_T - - - - - - - - - t - - q - - - - v - v_T - - - - - u_C - - - - - - - q - q_us - - C_T - - u_ext - - - - - u - - - u_C - - - R_v - - - v - v_T - - - - - - - - - - t - - v - - - - - - - - u_in - u - - - - - - v - R_T_wCont - - 2 - - - I_T - - - - - - - - t - - v_T - - - - - - - - u - u_out - - - - - - v_T - R_T_wCont - - 2 - - - I_T - - - - - R_T_wCont - - - - - R_T - Delta_R - - R_local_multiplier - - - - - - - - - - - - - - - - - - - - - - - - - - - R_v - - - 0.01 - C_T - - - - - - - - - t - - q - - - - v - v_T - - - - - u_C - - - - - - - q - q_us - - C_T - - u_ext - - - - - u - - - u_C - - - R_v - - - v - v_T - - - - - - - - - - t - - v - - - - - - - - u_in - u - - - - - - v - R_T_wCont - - 2 - - - I_T - - - - - - - - t - - v_T - - - - - - - - u - u_out - - - - - - v_T - R_T_wCont - - 2 - - - I_T - - - - - R_T_wCont - - - - - R_T - Delta_R - - R_local_multiplier - - - - - - - - - - - - - - - - - - - - - - - - R_v - - - 0.01 - C_T - - - - - I_T - 1-6 - - - - - - - - t - - q - - - - v - v_T - - - - - u_C - - - - - q - q_us - - C_T - - - - - u - - - u_C - u_ext - - - R_v - - - v - v_T - - - - - - - - - - t - - v - - - - - - - - u_in - u - - - - - - v - R_T - - 2 - - - I_T - - - - - - - - t - - v_T - - - - - - - - u - u_out - - - - - - v_T - R_T - - 2 - - - I_T - - - - - - - - - - - - - - - - - - - - - - - - R_v - - - 0.01 - C_T - - - - - I_T - 1-6 - - - - - - - - t - - q - - - - v - v_T - - - - - u_C - - - - - q - q_us - - C_T - - - - - u - - - u_C - u_ext - - - R_v - - - v - v_T - - - - - - - - - - t - - v - - - - - - - - u_in - u - - - - - - v - R_T - - 2 - - - I_T - - - - - - - - t - - v_T - - - - - - - - u - u_out - - - - - - v_T - R_T - - 2 - - - I_T - - - - - - - - - - - - - - - - - - - - - - - - R_v - - - 0.01 - C_T - - - - - I_T - 1-6 - - - - - - - - t - - q - - - - v - v_T - - - - - u_C - - - - - q - q_us - - C_T - - - - - u - - - u_C - u_ext - - - R_v - - - v - v_T - - - - - - - - - - t - - v - - - - - - - - u_in - u - - - - - - v - R_T - - 2 - - - I_T - - - - - - - - t - - v_T - - - - - - - - u - u_out - - - - - - v_T - R_T - - 2 - - - I_T - - - - - - - - - - - - - - - - - - - - - - - - R_v - - - 0.01 - C_T - - - - - I_T - 1-6 - - - - - - - - t - - q - - - - v - v_T - - - - - u_C - - - - - q - q_us - - C_T - - - - - u - - - u_C - u_ext - - - R_v - - - v - v_T - - - - - - - - - - t - - v - - - - - - - - u_in - u - - - - - - v - R_T - - 2 - - - I_T - - - - - - - - t - - v_T - - - - - - - - u - u_out - - - - - - v_T - R_T - - 2 - - - I_T - - - - - - - - - - - - - - - - - - - - - - - - R_v - - - 0.01 - C_T - - - - - I_T - 1-6 - - - - - - - - t - - q - - - - v - v_T - - - - - u_C - - - - - q - q_us - - C_T - - - - - u - - - u_C - u_ext - - - R_v - - - v - v_T - - - - - - - - - - t - - v - - - - - - - - u_in - u - - - - - - v - R_T - - 2 - - - I_T - - - - - - - - t - - v_T - - - - - - - - u - u_out - - - - - - v_T - R_T - - 2 - - - I_T - - - - - - - - - - - - - - - - - - - - - - - - R_v - - - 0.01 - C_T - - - - - I_T - 1-6 - - - - - - - - t - - q - - - - v - v_T - - - - - u_C - - - - - q - q_us - - C_T - - - - - u - - - u_C - u_ext - - - R_v - - - v - v_T - - - - - - - - - - t - - v - - - - - - - - u_in - u - - - - - - v - R_T - - 2 - - - I_T - - - - - - - - t - - v_T - - - - - - - - u - u_out - - - - - - v_T - R_T - - 2 - - - I_T - - - - - - - - - - - - - - - - - - - - - - - - R_v - - - 0.01 - C_T - - - - - I_T - 1-6 - - - - - - - - t - - q - - - - v - v_T - - - - - u_C - - - - - q - q_us - - C_T - - - - - u - - - u_C - u_ext - - - R_v - - - v - v_T - - - - - - - - - - t - - v - - - - - - - - u_in - u - - - - - - v - R_T - - 2 - - - I_T - - - - - - - - t - - v_T - - - - - - - - u - u_out - - - - - - v_T - R_T - - 2 - - - I_T - - - - - - - - - - - - - - - - - - - - - - - - R_v - - - 0.01 - C_T - - - - - I_T - 1-6 - - - - - - - - t - - q - - - - v - v_T - - - - - u_C - - - - - q - q_us - - C_T - - - - - u - - - u_C - u_ext - - - R_v - - - v - v_T - - - - - - - - - - t - - v - - - - - - - - u_in - u - - - - - - v - R_T - - 2 - - - I_T - - - - - - - - t - - v_T - - - - - - - - u - u_out - - - - - - v_T - R_T - - 2 - - - I_T - - - - - - - - - - - - - - - - - - - - - - - - R_v - - - 0.01 - C_T - - - - - I_T - 1-6 - - - - - - - - t - - q - - - - v - v_T - - - - - u_C - - - - - q - q_us - - C_T - - - - - u - - - u_C - u_ext - - - R_v - - - v - v_T - - - - - - - - - - t - - v - - - - - - - - u_in - u - - - - - - v - R_T - - 2 - - - I_T - - - - - - - - t - - v_T - - - - - - - - u - u_out - - - - - - v_T - R_T - - 2 - - - I_T - - - - - - - - - - - - - - - - - - - - - - - - R_v - - - 0.01 - C_T - - - - - I_T - 1-6 - - - - - - - - t - - q - - - - v - v_T - - - - - u_C - - - - - q - q_us - - C_T - - - - - u - - - u_C - u_ext - - - R_v - - - v - v_T - - - - - - - - - - t - - v - - - - - - - - u_in - u - - - - - - v - R_T - - 2 - - - I_T - - - - - - - - t - - v_T - - - - - - - - u - u_out - - - - - - v_T - R_T - - 2 - - - I_T - - - - - - - - - - - - - - - - - - - - - - - - R_v - - - 0.01 - C_T - - - - - I_T - 1-6 - - - - - - - - t - - q - - - - v - v_T - - - - - u_C - - - - - q - q_us - - C_T - - - - - u - - - u_C - u_ext - - - R_v - - - v - v_T - - - - - - - - - - t - - v - - - - - - - - u_in - u - - - - - - v - R_T - - 2 - - - I_T - - - - - - - - t - - v_T - - - - - - - - u - u_out - - - - - - v_T - R_T - - 2 - - - I_T - - - - - - - - - - - - - - - - - - - - - - - - R_v - - - 0.01 - C_T - - - - - I_T - 1-6 - - - - - - - - t - - q - - - - v - v_T - - - - - u_C - - - - - q - q_us - - C_T - - - - - u - - - u_C - u_ext - - - R_v - - - v - v_T - - - - - - - - - - t - - v - - - - - - - - u_in - u - - - - - - v - R_T - - 2 - - - I_T - - - - - - - - t - - v_T - - - - - - - - u - u_out - - - - - - v_T - R_T - - 2 - - - I_T - - - - - - - - - - - - - - - - - - - - - - - - R_v - - - 0.01 - C_T - - - - - I_T - 1-6 - - - - - - - - t - - q - - - - v - v_T - - - - - u_C - - - - - q - q_us - - C_T - - - - - u - - - u_C - u_ext - - - R_v - - - v - v_T - - - - - - - - - - t - - v - - - - - - - - u_in - u - - - - - - v - R_T - - 2 - - - I_T - - - - - - - - t - - v_T - - - - - - - - u - u_out - - - - - - v_T - R_T - - 2 - - - I_T - - - - - - - - - - - - - - - - - - - - - - - - R_v - - - 0.01 - C_T - - - - - I_T - 1-6 - - - - - - - - t - - q - - - - v - v_T - - - - - u_C - - - - - q - q_us - - C_T - - - - - u - - - u_C - u_ext - - - R_v - - - v - v_T - - - - - - - - - - t - - v - - - - - - - - u_in - u - - - - - - v - R_T - - 2 - - - I_T - - - - - - - - t - - v_T - - - - - - - - u - u_out - - - - - - v_T - R_T - - 2 - - - I_T - - - - - - - - - - - - - - - - - - - - - - - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - u - u_out - - - - R - v - - - I - - - - - - - - t - - q_C_change - - - - v_in - v - - - - - q_C - - - - - q_C_change - q_us_0 - - q_us_wCont - - - - - q - - - q_C - q_us_wCont - - - - - u_C - - - - - q_C - C_wCont - - u_ext - - - - - u - - - u_C - - - R_v - - - v_in - v - - - - - - - q_us_wCont - - - q_us_0 - - - 1 - Delta_q_us - - - - - - C_wCont - - - C - - - 1 - Delta_C - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - u - u_out - - - - R - v - - - I - - - - - - - - t - - q_C_change - - - - v_in - v - - - - - q_C - - - - - q_C_change - q_us_0 - - q_us_wCont - - - - - q - - - q_C - q_us_wCont - - - - - u_C - - - - - q_C - C_wCont - - u_ext - - - - - u - - - u_C - - - R_v - - - v_in - v - - - - - - - q_us_wCont - - - q_us_0 - - - 1 - Delta_q_us - - - - - - C_wCont - - - C - - - 1 - Delta_C - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - u - u_out - - - - R - v - - - I - - - - - - - - t - - q_C_change - - - - v_in - v - - - - - q_C - - - - - q_C_change - q_us_0 - - q_us_wCont - - - - - q - - - q_C - q_us_wCont - - - - - u_C - - - - - q_C - C_wCont - - u_ext - - - - - u - - - u_C - - - R_v - - - v_in - v - - - - - - - q_us_wCont - - - q_us_0 - - - 1 - Delta_q_us - - - - - - C_wCont - - - C - - - 1 - Delta_C - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - u - u_out - - - - R - v - - - I - - - - - - - - t - - q_C_change - - - - v_in - v - - - - - q_C - - - - - q_C_change - q_us_0 - - q_us_wCont - - - - - q - - - q_C - q_us_wCont - - - - - u_C - - - - - q_C - C_wCont - - u_ext - - - - - u - - - u_C - - - R_v - - - v_in - v - - - - - - - q_us_wCont - - - q_us_0 - - - 1 - Delta_q_us - - - - - - C_wCont - - - C - - - 1 - Delta_C - - - - - - - - - - - - - - - - - - - - - - - - - t - - P_baro - - - - - - - - P_sys - - - tau_zb - dP_sys_dt - - - P_baro - - tau_pb - - - - - f_ab - - - - - f_ab_min - - - f_ab_max - - - - - - - P_baro - P_nom - - k_ab - - - - - - - 1 - - - - - - - P_baro - P_nom - - k_ab - - - - - - - - - - - - - - - - - - - - - - f_v - - - - - - - - - f_ev_0 - - - f_ev_inf - - - - - - - f_ab - f_ab_0 - - k_ev - - - - - - - 1 - - - - - - - f_ab - f_ab_0 - - k_ev - - - - - - - W_cv - f_apc - - - theta_v - - - - - - - - - - - - - - - - - - - - f_s_premax - - - f_es_inf - - - - - f_es_0 - f_es_inf - - - - - - k_es - - - - - W_bs - f_ab - - - - W_cs - f_apc - - - - - - - - - - f_s - - - f_s_premax - - - f_s_premax - f_es_max - - - - f_es_max - - - - - - - - - - - - - - - - - sigma_theta - - - - - G_theta - - - - - 1 - - - - - f_s - f_es_min - - 1 - - - - - - - f_s - f_es_min - - - - 0 - - - - - - - - - t - - Delta_theta - - - - - - - - Delta_theta - - sigma_theta - - tau_theta - - - - - - - - - - - - - - - - sigma_theta - - - - - G_theta - - - - - 1 - - - - - f_s - f_es_min - - 1 - - - - - - - f_s - f_es_min - - - - 0 - - - - - - - - - t - - Delta_theta - - - - - - - - Delta_theta - - sigma_theta - - tau_theta - - - - - - - - - - - - - - - - sigma_theta - - - - - G_theta - - - - - 1 - - - - - f_s - f_es_min - - 1 - - - - - - - f_s - f_es_min - - - - 0 - - - - - - - - - t - - Delta_theta - - - - - - - - Delta_theta - - sigma_theta - - tau_theta - - - - - - - - - - - - - - - - sigma_theta - - - - - G_theta - - - - - 1 - - - - - f_s - f_es_min - - 1 - - - - - - - f_s - f_es_min - - - - 0 - - - - - - - - - t - - Delta_theta - - - - - - - - Delta_theta - - sigma_theta - - tau_theta - - - - - - - - - - - - - - - - - - - - - - sigma_Ts - - - - - G_Ts - - - - - 1 - - - - - f_s - f_es_min - - 1 - - - - - - - f_s - f_es_min - - - - 0 - - - - - - - - - t - - Delta_Ts - - - - - - - - Delta_Ts - - sigma_Ts - - tau_Ts - - - - - sigma_Tv - - - G_Tv - f_v - - - - - - - - t - - Delta_Tv - - - - - - - - Delta_Tv - - sigma_Tv - - tau_Tv - - - - - Delta_T - - - Delta_Tv - Delta_Ts - - - - - - - - - - - - - - - - - - - - - - - t - - sigma_theta_us - - - - - - - - - - f_s - f_es_min - - 0 - - sigma_theta_us - - tau_theta_us - - - - - Delta_theta_us - - - - - G_theta_compliance - sigma_theta_us - - - - f_es_min - sigma_theta_us - - - - - - - - - t - - sigma_theta_compliance - - - - - - - - - - f_s - f_es_min - - 0 - - sigma_theta_compliance - - tau_theta_compliance - - - - - Delta_theta_compliance - - - - - G_theta_compliance - sigma_theta_compliance - - - - f_es_min - sigma_theta_compliance - - - - - - - - - - - - - - - - - - - - - - - - - q - - - q_C - q_0 - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - u - u_out - - - - R - v - - - I - - - - - - - - t - - q_C - - - - v_in - v - - - - - u_C - - - - - q_C - C - - u_ext - - - - - u - - - u_0 - u_C - - - R_v - - - v_in - v - - - - - - - - - - - - - - - - - - - - - - - - - - q - - - q_C - q_0 - - - - - R_v - - - 0.01 - C - - - - - - - - - t - - v - - - - - - - - u - u_out - - - - R - v - - - I - - - - - - - - t - - q_C - - - - v_in - v - - - - - u_C - - - - - q_C - C - - u_ext - - - - - u - - - u_0 - u_C - - - R_v - - - v_in - v - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - v_venous_lb - - - v_A_internal_iliac_L_T - v_A_internal_iliac_R_T - v_A_profunda_femoris_L_T - v_A_profunda_femoris_R_T - v_A_anterior_tibial_L_T - v_A_anterior_tibial_R_T - v_A_posterior_tibial_L_T - v_A_fibular_L_T - v_A_fibular_R_T - v_A_posterior_tibial_R_T - - - - - - - v_venous_ub - - - v_A_left_gastric_C_T - v_A_common_hepatic_C_T - v_A_splenic_C_T - v_A_superior_mesenteric_C_T - v_A_renal_L_T - v_A_renal_R_T - v_A_inferior_mesenteric_C_T - v_A_radial_L_T - v_A_ulnar_L_T - v_A_radial_R_T - v_A_ulnar_R_T - v_A_external_carotid_L_T - v_A_external_carotid_R_T - v_A_posterior_inferior_cerebellar_R_T - v_A_posterior_inferior_cerebellar_L_T - v_A_anterior_inferior_cerebellar_R_T - v_A_anterior_inferior_cerebellar_L_T - v_A_superior_cerebellar_L_T - v_A_middle_cerebral_L_T - v_A_superior_cerebellar_R_T - v_A_middle_cerebral_R_T - v_A_posterior_cerebral_postcommunicating_part_L_T - v_A_posterior_cerebral_postcommunicating_part_R_T - v_A_anterior_cerebral_L_2_T - v_A_anterior_cerebral_R_2_T - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -