Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't set integrator from rrtests #833

Open
luciansmith opened this issue Sep 16, 2021 · 5 comments · Fixed by #841
Open

Can't set integrator from rrtests #833

luciansmith opened this issue Sep 16, 2021 · 5 comments · Fixed by #841
Assignees

Comments

@luciansmith
Copy link

luciansmith commented Sep 16, 2021

For some reason, when the rrtests try to set the integrator to 'rk4' or 'rk45' in C++, it fails because there are zero registered integrators (as far as I can tell). For now, I just disabled those test sections, but it would be nice to figure out why and fix this. I think the integrator factory mechanism was set up by Ciaran, so I'm assigning this to him for now.

The tests can be re-enabled in the functions check_CHECK_RK4_OUTPUT and check_CHECK_RK45_OUTPUT at lines 998 and 1023 of RRTestFileTests.cpp

@CiaranWelsh
Copy link

The mechanism for setting Integrators (and solvers in general) was already around before I got there. I did however refactor it a little to remove some of the clunkyness.

As far as registered intergrators in Python goes, they look like they are working based on

    # python_api_tests.py
    .
    .
    .
    def test_getRegisteredIntegratorNames(self):
        self.assertEqual(
            ('cvode', 'gillespie', 'rk4', 'rk45', 'euler'),
            self.rr.getRegisteredIntegratorNames(),
        )

    def test_getRegisteredSteadyStateSolverNames(self):
        self.assertEqual(
            ('nleq1', 'nleq2', 'newton', "newton_linesearch"),
            self.rr.getRegisteredSteadyStateSolverNames(),
        )

    def test_getRegisteredSensitivitySolverNames(self):
        print(dir(self.rr))
        self.assertEqual(
            ("forward",),
            self.rr.getRegisteredSensitivitySolverNames(),
        )
    .
    .
    .

@CiaranWelsh
Copy link

It seems all is working from the C++ API:

// RoadRunnerAPITests.cpp

TEST_F(RoadRunnerAPITests, setIntegratorToRk4){
    RoadRunner rr(SimpleFlux().str());
    rr.setIntegrator("rk4");
    ASSERT_STREQ("rk4", rr.getIntegrator()->getName().c_str());
}

TEST_F(RoadRunnerAPITests, setIntegratorToRk45){
    RoadRunner rr(SimpleFlux().str());
    rr.setIntegrator("rk45");
    ASSERT_STREQ("rk45", rr.getIntegrator()->getName().c_str());
}

So the problem must be with the C API

@CiaranWelsh
Copy link

I took all the various bits of code that collectively make up that test and put them into a new test (see below). Thing is, it passes - so my guess is that its a bug in the test suite resulting from using a shared state between tests (i.e. global variables). It could take a long time to debug this so I'm going to move on to something that needs doing for the release.


TEST_F(CAPICoreTest, CheckRK4WorksFromC) {
    // This code is the contents of createRRInstance in the C api
    char *capiLocation = getRRCAPILocation(); // return type is dynamically allocated.
    string rrInstallFolder(getParentFolder(capiLocation));
    free(capiLocation);
    std::filesystem::path supportCodeDir = std::filesystem::path(rrInstallFolder) /= "rr_support";
    auto *rr = new RoadRunner("", getTempDir(), supportCodeDir.string());
    // end

    // This code is from the top of checkRRTest
    path rrTestFileDir = rrTestDir_ / "rrtest_files";
    path rrTestFileName = rrTestFileDir / "Test_1.rrtest";

    // This code from check_LoadData
    // need to re-assign it, Load does not clear old data.;

    IniFile iniFile;
    iniFile.Clear();

    EXPECT_TRUE(std::filesystem::exists(rrTestFileName));
    EXPECT_TRUE(iniFile.Load(rrTestFileName.string()));

    IniSection *sbmlsec = iniFile.GetSection("SBML");
    if (!sbmlsec) {
        EXPECT_TRUE(false);
        return;
    }
    sbmlsec->mIsUsed = true;
    string sbml = sbmlsec->GetNonKeysAsString();
    if (sbml.find('<') == string::npos) {
        sbml = (rrTestDir_ / path("rrtest_files") / sbml).string();
        EXPECT_TRUE(std::filesystem::exists(sbml));
    }
    if (!loadSBMLEx(rr, sbml.c_str(), true)) {
        EXPECT_TRUE(false);
    }

    SimulateOptions opt;
    opt.start = 0;
    opt.duration = 10;
    auto *cvode = rr->simulate(&opt);

    rr->setIntegrator("rk4");
    auto *rk4 = rr->simulate(&opt);
    for (int k = 0; k < cvode->CSize(); k++) {
        EXPECT_NEAR((*cvode)(cvode->RSize() - 1, k), (*rk4)(rk4->RSize() - 1, k), 1e-6);
    }
}

@luciansmith
Copy link
Author

I'm re-opening this since it wasn't resolved, but I 100% agree that it's a low-priority issue.

(Also, I'm editing my description because I meant to say 'in C++' instead of 'in python'.)

@luciansmith luciansmith reopened this Sep 17, 2021
@CiaranWelsh
Copy link

Yes, this accidently closed because I merged a fix for something else with related histories (or something).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants