void TestCardiacSimulationArchiveDynamic() throw(Exception)
    {
#ifdef CHASTE_CAN_CHECKPOINT_DLLS
        // run a monodomain simulation
        {
            CardiacSimulation simulation("heart/test/data/xml/save_monodomain_dynamic.xml");
        }
        std::string foldername = "SaveMonodomainDynamic";

        // compare the files, using the CompareFilesViaHdf5DataReader() method
        TS_ASSERT( CompareFilesViaHdf5DataReader("heart/test/data/cardiac_simulations", "save_monodomain_dynamic", false,
                   foldername, "SimulationResults", true));

        FileFinder file(foldername + "_checkpoints/0.2ms/" + foldername + "_0.2ms/archive.arch.0",
                        RelativeTo::ChasteTestOutput);
        TS_ASSERT(file.Exists());

        /* If you want to update the .h5 results for this test for any reason, you need to stop the following lines adding to them.
         * So uncomment the assert(), run the test, and then do:
         cp /tmp/chaste/testoutput/SaveMonodomainDynamic/SimulationResults.h5 heart/test/data/cardiac_simulations/save_monodomain_dynamic.h5
         */
        //assert(0);

        //resume the simulation
        {
            CardiacSimulation simulation("heart/test/data/xml/resume_monodomain_dynamic.xml");
        }

        // compare the files, using the CompareFilesViaHdf5DataReader() method
        TS_ASSERT( CompareFilesViaHdf5DataReader("heart/test/data/cardiac_simulations", "resume_monodomain_dynamic", false,
                   foldername, "SimulationResults", true));

#endif // CHASTE_CAN_CHECKPOINT_DLLS
    }
    void TestCardiacSimulationPostprocessMonodomain() throw(Exception)
    {
        // run a bidomain simulation
        CardiacSimulation simulation("heart/test/data/xml/postprocess_monodomain.xml");
        std::string foldername = "PostprocessMonodomainNightly/";

        // compare the files, using the CompareFilesViaHdf5DataReader() method
        TS_ASSERT( CompareFilesViaHdf5DataReader("heart/test/data/cardiac_simulations", "postprocess_monodomain_results", false,
                                                 foldername, "SimulationResults", true, 1e-9));
    }
    void TestCardiacSimulationBasicMonodomainShort() throw(Exception)
    {
        // Fox2002BackwardEuler cell model
        // run a bidomain simulation
        CardiacSimulation simulation("heart/test/data/xml/base_monodomain_short.xml");

       // compare the files, using the CompareFilesViaHdf5DataReader() method
        TS_ASSERT( CompareFilesViaHdf5DataReader("heart/test/data/cardiac_simulations", "base_monodomain_short_results", false,
                                                 "BaseMonodomainShort", "SimulationResults", true, 1e-6));
    }
    // requires TestCardiacSimulationArchiveMonodomain() to have been run
    void TestCardiacSimulationResumeMonodomain() throw(Exception)
    {
        // run a monodomain simulation
        HeartConfig::Instance()->SetSpaceDimension(1);
        CardiacSimulation simulation("heart/test/data/xml/resume_monodomain_short.xml");
        std::string foldername = "SaveMonodomainShort";

        // compare the files, using the CompareFilesViaHdf5DataReader() method
        TS_ASSERT( CompareFilesViaHdf5DataReader("heart/test/data/cardiac_simulations", "resume_monodomain_short_results", false,
                                                 foldername, "SimulationResults", true, 1e-6));
    }
    void TestCardiacSimulationPostprocessMonodomain() throw(Exception)
    {
        // Fox2002BackwardEuler cell model
        // run a bidomain simulation
        CardiacSimulation simulation("heart/test/data/xml/postprocess_monodomain_short.xml");
        std::string foldername = "PostprocessMonodomainShort";

        // compare the files, using the CompareFilesViaHdf5DataReader() method
        TS_ASSERT( CompareFilesViaHdf5DataReader("heart/test/data/cardiac_simulations", "postprocess_monodomain_short_results", false,
                                                 foldername, "SimulationResults", true, 1e-6));
    }
    void TestMono1dSodiumBlockBySettingNamedParameter() throw(Exception)
    {
        CardiacSimulation simulation("heart/test/data/xml/monodomain1d_sodium_block.xml");
        TS_ASSERT( CompareFilesViaHdf5DataReader("heart/test/data/cardiac_simulations", "mono_1d_sodium_block", false,
                                                 "Mono1dSodiumBlock", "SimulationResults", true,
                                                 2.5e-3));

        // Test exception
        TS_ASSERT_THROWS_THIS(CardiacSimulation bad_param("heart/test/data/xml/bad_cell_parameter.xml"),
                              "No parameter named 'missing-parameter'.");
    }
 void TestMonoStimUsingEllipsoids() throw(Exception)
 {
     if (PetscTools::GetNumProcs() > 3u)
     {
         TS_TRACE("This test is not suitable for more than 3 processes.");
         return;
     }
     // Fox2002BackwardEuler cell model
     CardiacSimulation simulation("heart/test/data/xml/monodomain1d_stim_using_ellipsoid.xml", true);
     TS_ASSERT( CompareFilesViaHdf5DataReader("heart/test/data/cardiac_simulations", "monodomain1d_stim_using_ellipsoid", false,
                                              "Mono1DStimUsingEllipsoid", "SimulationResults", true, 1e-6));
 }
    void TestCardiacSimulationSaveBidomain() throw(Exception)
    {
        // run a bidomain simulation
        CardiacSimulation simulation("heart/test/data/xml/save_bidomain.xml");
        std::string foldername = "SaveBidomainNightly";

        // compare the files, using the CompareFilesViaHdf5DataReader() method
        TS_ASSERT( CompareFilesViaHdf5DataReader("heart/test/data/cardiac_simulations", "save_bidomain_results", false,
                                                 foldername, "SimulationResults", true, 1e-9));

        FileFinder file(foldername + "_checkpoints/10ms/" + foldername + "_10ms/archive.arch.0",
                        RelativeTo::ChasteTestOutput);
        TS_ASSERT(file.Exists());
    }
    // requires TestCardiacSimulationArchiveBidomain() to have been run
    void TestCardiacSimulationResumeBidomain() throw(Exception)
    {
        // run a bidomain simulation
        HeartConfig::Instance()->SetSpaceDimension(1);
        FileFinder resume_xml("heart/test/data/xml/resume_bidomain_short.xml", RelativeTo::ChasteSourceRoot);
        OutputFileHandler checkpoint_dir("SaveBidomainShort_checkpoints/0.2ms", false);
        FileFinder copied_xml = checkpoint_dir.CopyFileTo(resume_xml);
        CardiacSimulation simulation(copied_xml.GetAbsolutePath());
        std::string foldername = "SaveBidomainShort";

        // compare the files, using the CompareFilesViaHdf5DataReader() method
        TS_ASSERT( CompareFilesViaHdf5DataReader("heart/test/data/cardiac_simulations", "resume_bidomain_short_results", false,
                                                 foldername, "SimulationResults", true, 1e-5));
        //assert(0);
    }
    void TestMono1dSmall() throw(Exception)
    {
        if (PetscTools::GetNumProcs() > 3u)
        {
            TS_TRACE("This test is not suitable for more than 3 processes.");
            return;
        }
        // Fox2002BackwardEuler cell model
        CardiacSimulation simulation("heart/test/data/xml/monodomain1d_small.xml", true);
        TS_ASSERT( CompareFilesViaHdf5DataReader("heart/test/data/cardiac_simulations", "mono_1d_small", false,
                                                 "SaveMono1D", "SimulationResults", true, 1e-6));

        /* If the above fails, and you are happy the new results are correct, uncomment the following line,
         * run the test, and then do
         cp /tmp/$USER/testoutput/SaveMono1D/SimulationResults.h5 heart/test/data/cardiac_simulations/mono_1d_small.h5
         */
        //assert(0);

        CardiacSimulation simulation2("heart/test/data/xml/monodomain1d_resume.xml", true);
    }
    void TestCardiacSimulationArchiveMonodomain() throw(Exception)
    {
        // Fox2002BackwardEuler cell model
        // run a bidomain simulation
        CardiacSimulation simulation("heart/test/data/xml/save_monodomain_short.xml");
        std::string foldername = "SaveMonodomainShort";

        // compare the files, using the CompareFilesViaHdf5DataReader() method
        TS_ASSERT( CompareFilesViaHdf5DataReader("heart/test/data/cardiac_simulations", "save_monodomain_short_results", false,
                                                 foldername, "SimulationResults", true, 1e-6));

        FileFinder file(foldername + "_checkpoints/0.2ms/" + foldername + "_0.2ms/archive.arch.0",
                        RelativeTo::ChasteTestOutput);
        TS_ASSERT(file.Exists());
        /* If you want to update the .h5 results for this test for any reason, you need to stop the following test adding to them.
         * So uncomment the assert(), run the test, and then do:
         cp /tmp/chaste/testoutput/SaveMonodomainShort/SimulationResults.h5 heart/test/data/cardiac_simulations/save_monodomain_short_results.h5
         */
        //assert(0);
    }
        FileFinder from_directory2(source_directory + folder_2, RelativeTo::ChasteSourceRoot);

        TRY_IF_MASTER(
            to_directory1.Remove();
            to_directory2.Remove();
            TS_ASSERT_EQUALS(to_directory1.Exists(), false);
            TS_ASSERT_EQUALS(to_directory2.Exists(), false);
            from_directory1.CopyTo(to_directory1);
            from_directory2.CopyTo(to_directory2);
        );

        // Resume
        CardiacSimulation simulation("heart/test/data/xml/resume_migration.xml");

        // Compare results
        TS_ASSERT( CompareFilesViaHdf5DataReader("heart/test/data/cardiac_simulations", "resume_bidomain_short_results", false,
                                                 "SaveBidomainShort", "SimulationResults", true, 1e-5));
    }

    void runSimulation(const std::string& rParametersFileName)
    {
        CardiacSimulation simulation(rParametersFileName);
    }

    void checkParameter(AbstractCardiacCellInterface* pCell, unsigned globalIndex)
    {
        // Check one of the parameters has been set in the central region
        TS_ASSERT_EQUALS(pCell->GetNumberOfParameters(), 3u);
        double expected_value;
        if (globalIndex <= 4 || globalIndex >= 16)
        {
            expected_value = 23.0;
    /**
     * This test is aimed at comparing the extended bidomain implementation in Chaste with
     * the original Finite Difference code developed by Martin Buist.
     *
     * All the parameters are chosen to replicate the same conditions as in his code.
     */
    void TestExtendedProblemVsMartincCode() throw (Exception)
    {
        SetupParameters();

        TetrahedralMesh<1,1> mesh;
        unsigned number_of_elements = 100;//this is nGrid in Martin's code
        double length = 10.0;//100mm as in Martin's code
        mesh.ConstructRegularSlabMesh(length/number_of_elements, length);
        TS_ASSERT_EQUALS(mesh.GetNumAllNodes(), number_of_elements + 1);

        double Am_icc = 1000.0;
        double Am_smc = 1000.0;
        double Am_gap = 1.0;
        double Cm_icc = 1.0;
        double Cm_smc = 1.0;
        double G_gap = 20.0;//mS/cm^2

        HeartConfig::Instance()->SetSimulationDuration(1000.0);  //ms.

        ICC_Cell_factory icc_factory;
        SMC_Cell_factory smc_factory;

        std::string dir = "ICCandSMC";
        std::string filename = "extended1d";
        HeartConfig::Instance()->SetOutputDirectory(dir);
        HeartConfig::Instance()->SetOutputFilenamePrefix(filename);

        ExtendedBidomainProblem<1> extended_problem( &icc_factory , &smc_factory);
        extended_problem.SetMesh(&mesh);

        extended_problem.SetExtendedBidomainParameters(Am_icc,Am_smc, Am_gap, Cm_icc, Cm_smc, G_gap);
        extended_problem.SetIntracellularConductivitiesForSecondCell(Create_c_vector(1.0));

        std::vector<unsigned> outputnodes;
        outputnodes.push_back(50u);
        HeartConfig::Instance()->SetRequestedNodalTimeTraces(outputnodes);

        extended_problem.Initialise();
        extended_problem.Solve();
        HeartEventHandler::Headings();
        HeartEventHandler::Report();

        /**
         * Compare with valid data.
         * As Martin's code is an FD code, results will never match exactly.
         * The comparison below is done against a 'valid' h5 file.
         *
         * The h5 file (1DValid.h5) is a Chaste (old phi_i formulation) file with is valid because, when extrapolating results from it, they look very similar
         * (except for a few points at the end of the upstroke) to the results taken
         * directly from Martin's code.
         * A plot of Chaste results versus Martin's result (at node 50) is stored
         * in the file 1DChasteVsMartin.eps for reference.
         *
         * A second plot comparing the old formulation (with phi_i) to the new formulation with V_m is contained in
         *.1DChasteNewFormulation.png
         *
         */
         TS_ASSERT( CompareFilesViaHdf5DataReader("heart/test/data/extendedbidomain", "1DValid", false,
                                                dir, filename, true,
                                                0.2));
         /*
          * Here we compare the new formulation (V_m1, V_m2, phi_e)
          *  with the previous formulation (phi_i1, phi_i2, phi_e) running with GMRES and an absolute KSP tolerance of 1e-8.
          */
         TS_ASSERT( CompareFilesViaHdf5DataReader("heart/test/data/extendedbidomain", "extended1d_previous_chaste_formulation_abs_tol_1e-8", false,
                                                dir, filename, true,
                                                1e-2));
    }