コード例 #1
0
ファイル: test_io.hpp プロジェクト: leavengood/rubinius
 void test_force_read_only() {
   io->force_read_only(state);
   TS_ASSERT((io->mode()->to_native() & O_ACCMODE) == O_RDONLY);
 }
コード例 #2
0
void pgsTestSuite::test_expression_record(void)
{
	pgsVarMap vars;

	pgsStmtList * SL1 = 0;

	wxArrayString columns;
	SL1 = pnew pgsStmtList(pgsTestClass::get_cout());

	{
		columns.Add(wxT("a"));
		columns.Add(wxT("b"));
		columns.Add(wxT("c"));
		columns.Add(wxT("d"));
	}

	// r := { a, b, c, d }
	{
		pgsStmt * S = 0;
		S = pnew pgsDeclareRecordStmt(wxT("r"), columns);
		SL1->insert_back(S);
	}

	// r[2][a] := 5
	{
		pgsStmt * S = 0;
		S = pnew pgsExpressionStmt(pnew pgsAssignToRecord(wxT("r"),
				pnew pgsNumber(wxT("2")), pnew pgsString(wxT("a")),
				pnew pgsNumber(wxT("5"))));
		SL1->insert_back(S);
	}

	// r[1][b] := "abc"
	{
		pgsStmt * S = 0;
		S = pnew pgsExpressionStmt(pnew pgsAssignToRecord(wxT("r"),
				pnew pgsNumber(wxT("1")), pnew pgsString(wxT("b")),
				pnew pgsString(wxT("abc"))));
		SL1->insert_back(S);
	}

	// r[0][0] := 1
	{
		pgsStmt * S = 0;
		S = pnew pgsExpressionStmt(pnew pgsAssignToRecord(wxT("r"),
				pnew pgsNumber(wxT("0")), pnew pgsNumber(wxT("0")),
				pnew pgsNumber(wxT("1"))));
		SL1->insert_back(S);
	}

	// w := r
	{
		pgsStmt * S = 0;
		S = pnew pgsExpressionStmt(pnew pgsAssign(wxT("w"),
				pnew pgsIdent(wxT("r"))));
		SL1->insert_back(S);
	}

	// p = (r != w)
	{
		pgsStmt * S = 0;
		S = pnew pgsExpressionStmt(pnew pgsAssign(wxT("p"),
				pnew pgsDifferent(pnew pgsIdent(wxT("r")),
				pnew pgsIdent(wxT("w")))));
		SL1->insert_back(S);
	}

	// r.remove_line(1)
	{
		pgsStmt * S = 0;
		S = pnew pgsExpressionStmt(pnew pgsRemoveLine(wxT("r"),
				pnew pgsNumber(wxT("1"))));
		TS_ASSERT(pgsRemoveLine(wxT("r"), pnew pgsNumber(wxT("1")))
				.value() == wxT("RMLINE(r[1])"));
		SL1->insert_back(S);
	}

	// q = (r != w)
	{
		pgsStmt * S = 0;
		S = pnew pgsExpressionStmt(pnew pgsAssign(wxT("q"),
				pnew pgsDifferent(pnew pgsIdent(wxT("r")),
				pnew pgsIdent(wxT("w")))));
		SL1->insert_back(S);
	}

	// o = (r < w)
	{
		pgsStmt * S = 0;
		S = pnew pgsExpressionStmt(pnew pgsAssign(wxT("o"),
				pnew pgsLower(pnew pgsIdent(wxT("r")),
				pnew pgsIdent(wxT("w")))));
		SL1->insert_back(S);
	}

	SL1->eval(vars);

	// Test symbol table at the end of the execution
	TS_ASSERT(vars[wxT("p")]->value() == wxT("0"));
	TS_ASSERT(vars[wxT("q")]->value() == wxT("1"));
	TS_ASSERT(vars[wxT("o")]->value() == wxT("1"));

	pdelete(SL1);
}
コード例 #3
0
    void TestOutputStatistics() throw(Exception)
    {
        EXIT_IF_PARALLEL;    // defined in PetscTools

        // Set up mesh
        unsigned num_cells_depth = 5;
        unsigned num_cells_width = 5;
        HoneycombMeshGenerator generator(num_cells_width, num_cells_depth, 0);
        MutableMesh<2,2>* p_mesh = generator.GetMesh();

        double crypt_length = (double)num_cells_depth *sqrt(3.0)/2.0;

        std::vector<unsigned> location_indices = generator.GetCellLocationIndices();

        // Set up cells
        std::vector<CellPtr> cells;
        CryptCellsGenerator<StochasticWntCellCycleModel> cell_generator;
        cell_generator.Generate(cells, p_mesh, location_indices, true);

        // Set up cell population
        MeshBasedCellPopulation<2> cell_population(*p_mesh, cells);
        cell_population.AddPopulationWriter<CellPopulationAreaWriter>();
        cell_population.AddCellWriter<CellVariablesWriter>();
        cell_population.AddPopulationWriter<CellProliferativePhasesCountWriter>();
        cell_population.AddCellWriter<CellProliferativePhasesWriter>();
        cell_population.AddCellWriter<CellAgesWriter>();

        // Set up Wnt Gradient
        WntConcentration<2>::Instance()->SetType(LINEAR);
        WntConcentration<2>::Instance()->SetCellPopulation(cell_population);
        WntConcentration<2>::Instance()->SetCryptLength(crypt_length);

        // Set up cell-based simulation
        OffLatticeSimulation<2> simulator(cell_population);
        TS_ASSERT_EQUALS(simulator.GetIdentifier(), "OffLatticeSimulation-2-2");
        simulator.SetOutputDirectory("OffLatticeSimulationWritingProteins");
        simulator.SetEndTime(0.5);

        // Create a force law and pass it to the simulation
        MAKE_PTR(GeneralisedLinearSpringForce<2>, p_linear_force);
        p_linear_force->SetCutOffLength(1.5);
        simulator.AddForce(p_linear_force);

        TS_ASSERT_DELTA(simulator.GetDt(), 1.0/120.0, 1e-12);

        // Run cell-based simulation
        TS_ASSERT_EQUALS(simulator.GetOutputDirectory(), "OffLatticeSimulationWritingProteins");
        TS_ASSERT_THROWS_NOTHING(simulator.Solve());

        OutputFileHandler handler("OffLatticeSimulationWritingProteins", false);

        std::string cell_variables_file = handler.GetOutputDirectoryFullPath() + "results_from_time_0/cellvariables.dat";
        NumericFileComparison comp_cell_variables(cell_variables_file, "crypt/test/data/OffLatticeSimulationWritingProteins/cellvariables.dat");
        TS_ASSERT(comp_cell_variables.CompareFiles(1e-2));

        std::string cell_cycle_file = handler.GetOutputDirectoryFullPath() + "results_from_time_0/cellcyclephases.dat";
        NumericFileComparison comp_cell_cycle(cell_cycle_file, "crypt/test/data/OffLatticeSimulationWritingProteins/cellcyclephases.dat");
        TS_ASSERT(comp_cell_cycle.CompareFiles(1e-2));

        std::string cell_ages_file = handler.GetOutputDirectoryFullPath() + "results_from_time_0/cellages.dat";
        NumericFileComparison comp_cell_ages(cell_ages_file, "crypt/test/data/OffLatticeSimulationWritingProteins/cellages.dat");
        TS_ASSERT(comp_cell_ages.CompareFiles(1e-2));

        // Tidy up
        WntConcentration<2>::Destroy();
    }
コード例 #4
0
    void TestArchivingOfPdeHandlerOnCuboid() throw(Exception)
    {
        EXIT_IF_PARALLEL;

        FileFinder archive_dir("archive", RelativeTo::ChasteTestOutput);
        std::string archive_file = "CellBasedPdeHandlerOnCuboid.arch";
        ArchiveLocationInfo::SetMeshFilename("pde_handler_mesh");

        {
            // Create a cell population
            HoneycombMeshGenerator generator(2, 2, 0);
            MutableMesh<2,2>* p_generating_mesh = generator.GetMesh();
            NodesOnlyMesh<2> mesh;
            mesh.ConstructNodesWithoutMesh(*p_generating_mesh, 1.5);

            std::vector<CellPtr> cells;
            CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator;
            cells_generator.GenerateBasic(cells, mesh.GetNumNodes());

            NodeBasedCellPopulation<2> cell_population(mesh, cells);

            // Create a PDE handler object using this cell population
            CellBasedPdeHandlerOnCuboid<2>* const p_pde_handler = new CellBasedPdeHandlerOnCuboid<2>(&cell_population);

            // Set member variables for testing
            p_pde_handler->SetWriteAverageRadialPdeSolution("averaged quantity", 5, true);
            p_pde_handler->SetImposeBcsOnCoarseBoundary(false);

            // Set up PDE and pass to handler
            AveragedSourcePde<2> pde(cell_population, -0.1);
            ConstBoundaryCondition<2> bc(1.0);
            PdeAndBoundaryConditions<2> pde_and_bc(&pde, &bc, false);
            pde_and_bc.SetDependentVariableName("averaged quantity");
            p_pde_handler->AddPdeAndBc(&pde_and_bc);

            // Test UseCoarsePdeMesh() again
            ChastePoint<2> lower(0.0, 0.0);
            ChastePoint<2> upper(9.0, 9.0);
            ChasteCuboid<2> cuboid(lower, upper);
            p_pde_handler->UseCoarsePdeMesh(3.0, cuboid, true);

            // Create an output archive
            ArchiveOpener<boost::archive::text_oarchive, std::ofstream> arch_opener(archive_dir, archive_file);
            boost::archive::text_oarchive* p_arch = arch_opener.GetCommonArchive();

            // Archive object
            SimulationTime* p_simulation_time = SimulationTime::Instance();
            p_simulation_time->SetEndTimeAndNumberOfTimeSteps(1.0, 11);
            (*p_arch) << static_cast<const SimulationTime&>(*p_simulation_time);
            (*p_arch) << p_pde_handler;

            // Tidy up
            SimulationTime::Destroy();
            delete p_pde_handler;
        }

        {
            CellBasedPdeHandlerOnCuboid<2>* p_pde_handler;

            // Create an input archive
            ArchiveOpener<boost::archive::text_iarchive, std::ifstream> arch_opener(archive_dir, archive_file);
            boost::archive::text_iarchive* p_arch = arch_opener.GetCommonArchive();

            // Restore object from the archive
            SimulationTime* p_simulation_time = SimulationTime::Instance();
            (*p_arch) >> *p_simulation_time;
            (*p_arch) >> p_pde_handler;

            // Test that the member variables were archived correctly
            TS_ASSERT_EQUALS(p_pde_handler->mpCellPopulation->GetNumRealCells(), 4u);
            TS_ASSERT_EQUALS(p_pde_handler->GetWriteAverageRadialPdeSolution(), true);
            TS_ASSERT_EQUALS(p_pde_handler->GetWriteDailyAverageRadialPdeSolution(), true);
            TS_ASSERT_EQUALS(p_pde_handler->GetImposeBcsOnCoarseBoundary(), false);
            TS_ASSERT_EQUALS(p_pde_handler->GetNumRadialIntervals(), 5u);
            TS_ASSERT_EQUALS(p_pde_handler->mAverageRadialSolutionVariableName, "averaged quantity");

            ///\todo we currently do not archive mpCoarsePdeMesh - consider doing this (#1891)
            TS_ASSERT(p_pde_handler->GetCoarsePdeMesh() == NULL);

            TS_ASSERT_EQUALS(p_pde_handler->mPdeAndBcCollection.size(), 1u);
            TS_ASSERT_EQUALS(p_pde_handler->mPdeAndBcCollection[0]->IsNeumannBoundaryCondition(), false);

            // Tidy up
            delete p_pde_handler->mpCellPopulation;
            delete p_pde_handler;
        }
    }
コード例 #5
0
    void TestSolvePdeAndWriteResultsToFileAndGetPDESolutionAtPointWithoutCoarsePdeMeshDirichlet() throw(Exception)
    {
        EXIT_IF_PARALLEL;

        // Set up SimulationTime
        SimulationTime::Instance()->SetEndTimeAndNumberOfTimeSteps(0.5, 6);

        // Set up mesh
        MutableMesh<2,2> mesh;
        TrianglesMeshReader<2,2> mesh_reader("mesh/test/data/disk_522_elements");
        mesh.ConstructFromMeshReader(mesh_reader);

        // Set up cells
        std::vector<CellPtr> cells;
        CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator;
        cells_generator.GenerateBasic(cells, mesh.GetNumNodes());

        // Set up cell population
        MeshBasedCellPopulation<2> cell_population(mesh, cells);

        // Create a PDE handler object using this cell population
        CellBasedPdeHandler<2> pde_handler(&cell_population);

        // Create a single PDE and pass to the handler
        SimplePdeForTesting pde;
        ConstBoundaryCondition<2> bc(1.0);
        PdeAndBoundaryConditions<2> pde_and_bc(&pde, &bc, false);
        pde_and_bc.SetDependentVariableName("variable");

        // For coverage, provide an initial guess for the solution
        std::vector<double> data(mesh.GetNumNodes());
        for (unsigned i=0; i<mesh.GetNumNodes(); i++)
        {
            data[i] = 1.0;
        }

        Vec vector = PetscTools::CreateVec(data);
        pde_and_bc.SetSolution(vector);

        pde_handler.AddPdeAndBc(&pde_and_bc);

        // Open result file ourselves
        OutputFileHandler output_file_handler("TestWritePdeSolution", false);
        pde_handler.mpVizPdeSolutionResultsFile = output_file_handler.OpenOutputFile("results.vizpdesolution");

        // Solve PDE (set sampling timestep multiple to be large doesn't do anything as always output on 1st timestep)
        pde_handler.SolvePdeAndWriteResultsToFile(10);

        // Close result file ourselves
        pde_handler.mpVizPdeSolutionResultsFile->close();

        // Test that this is correct by comparing with an existing results file
        std::string results_dir = output_file_handler.GetOutputDirectoryFullPath();

        NumericFileComparison comparison(results_dir + "results.vizpdesolution", "cell_based/test/data/TestCellBasedPdeHandler/results.vizpdesolution");
        TS_ASSERT(comparison.CompareFiles());

        // Check the correct solution was obtained
        for (AbstractCellPopulation<2>::Iterator cell_iter = cell_population.Begin();
             cell_iter != cell_population.End();
             ++cell_iter)
        {
            double radius = norm_2(cell_population.GetLocationOfCellCentre(*cell_iter));
            double analytic_solution = 1.0 - 0.25*(1 - pow(radius,2.0));

            // Test that PDE solver is working correctly
            TS_ASSERT_DELTA(cell_iter->GetCellData()->GetItem("variable"), analytic_solution, 0.02);
        }

        // Now check the GetPdeSolutionAtPoint method

        // First loop over nodes and check it works
        // Check the correct solution was obtained
        for (AbstractCellPopulation<2>::Iterator cell_iter = cell_population.Begin();
             cell_iter != cell_population.End();
             ++cell_iter)
        {
            double cell_data_solution(cell_iter->GetCellData()->GetItem("variable"));
            c_vector<double,2> cell_location = cell_population.GetLocationOfCellCentre(*cell_iter);

            TS_ASSERT_DELTA(pde_handler.GetPdeSolutionAtPoint(cell_location,"variable"), cell_data_solution, 1e-6);
        }

        // Now choose some other points

        // Centre
        c_vector<double,2> point;
        point(0) = 0.0;
        point(1) = 0.0;

        TS_ASSERT_DELTA(pde_handler.GetPdeSolutionAtPoint(point,"variable"), 0.75, 0.01);

        // Cover exception
        TS_ASSERT_THROWS_CONTAINS(pde_handler.GetPdeSolutionAtPoint(point, "not_a_var"),
                                  "There is no PDE with that variable.");

        // Random point
        point(0) = 0.5;
        point(1) = 0.5;

        TS_ASSERT_DELTA(pde_handler.GetPdeSolutionAtPoint(point,"variable"), 1.0 - (1.0-2.0*0.5*0.5)/4.0, 0.01);

        // Point on the boundary
        point(0) = 1.0;
        point(1) = 0.0;

        TS_ASSERT_DELTA(pde_handler.GetPdeSolutionAtPoint(point,"variable"), 1.0, 1e-6);
    }
コード例 #6
0
// see #1061
    void Test2dBathExtracellularStimulusOneEdgeGroundedOnOppositeEdge()
    {
        HeartConfig::Instance()->SetSimulationDuration(40);  //ms
        HeartConfig::Instance()->SetOutputDirectory("BidomainBath2dExtraStimGrounded");
        HeartConfig::Instance()->SetOutputFilenamePrefix("bidomain_bath_2d");

        HeartConfig::Instance()->SetOdeTimeStep(0.005);  //ms

        // need to create a cell factory but don't want any intra stim, so magnitude
        // of stim is zero.
        c_vector<double,2> centre;
        centre(0) = 0.05;
        centre(1) = 0.05;
        BathCellFactory<2> cell_factory( 0.0, centre);

        BidomainProblem<2> bidomain_problem( &cell_factory, true );

        TrianglesMeshReader<2,2> reader("mesh/test/data/2D_0_to_1mm_400_elements");
        TetrahedralMesh<2,2> mesh;
        mesh.ConstructFromMeshReader(reader);

        // Set everything outside a central circle (radius 0.4) to be bath
        for (unsigned i=0; i<mesh.GetNumElements(); i++)
        {
            double x = mesh.GetElement(i)->CalculateCentroid()[0];
            double y = mesh.GetElement(i)->CalculateCentroid()[1];
            if (sqrt((x-0.05)*(x-0.05) + (y-0.05)*(y-0.05)) > 0.02)
            {
                mesh.GetElement(i)->SetAttribute(HeartRegionCode::GetValidBathId());
            }
        }

        bidomain_problem.SetMesh(&mesh);

        //boundary flux for Phi_e
        //-4e3 is enough to trigger an action potential, -3e3 is below threshold, -5e3 crashes the cell model.
        double boundary_flux = -9e3;
        double duration = 2.5; //ms

        HeartConfig::Instance()->SetElectrodeParameters(true,0,boundary_flux, 0.0, duration);
        bidomain_problem.Initialise();
        bidomain_problem.Solve();

        Vec sol = bidomain_problem.GetSolution();
        ReplicatableVector sol_repl(sol);

        bool ap_triggered = false;
        /*
         * We are checking the last time step. This test will only make sure that an upstroke is triggered.
         * We ran longer simulation for 350 ms and a nice AP was observed.
         */
        for (unsigned i=0; i<mesh.GetNumNodes(); i++)
        {
            // test V = 0 for all bath nodes
            if (mesh.GetNode(i)->GetRegion()==1) // bath
            {
                TS_ASSERT_DELTA(sol_repl[2*i], 0.0, 1e-12);
            }
            else if (sol_repl[2*i] > 0.0)
            {
                ap_triggered = true;
            }
        }
        TS_ASSERT(ap_triggered);
    }
コード例 #7
0
    void TestAdvance()
    {
        const double smidge = 1e-10;

        double start_time = 0.0;
        double end_time = 2.0;
        double timestep = 3.7e-05;

        // This is how a time stepper is normally used
        TimeStepper my_stepper(start_time, end_time, timestep);
        while ( !my_stepper.IsTimeAtEnd() )
        {
            // do something

            my_stepper.AdvanceOneTimeStep();
        }

        // Tests
        TS_ASSERT_THROWS_THIS(TimeStepper(end_time, start_time, timestep),
                              "The simulation duration must be positive, not -2");

        // Note that the timestep in this test does not divide whole time interval nicely, therefore we can't enforce a constant timestep.
        bool enforce_constant_timestep = true;
        TS_ASSERT_THROWS_CONTAINS(TimeStepper(start_time, end_time, timestep, enforce_constant_timestep),
                                      "TimeStepper estimates non-constant timesteps will need to be used");

        TimeStepper stepper(start_time, end_time, timestep);

        TS_ASSERT_EQUALS(stepper.EstimateTimeSteps(), (unsigned) floor((end_time - start_time)/timestep) );

        double real_time_step = timestep;
        unsigned time_step_number = 0;
        double current_time = start_time;

        /*
         * We'll trap for stopping times that are close to the end time
         * in order to avoid having a timestep of 1e-14 (or whatever) at
         * the end in the case of rounding errors.
         */
        double close_to_end_time = end_time - smidge*timestep;

        while (current_time < end_time)
        {
            TS_ASSERT(!stepper.IsTimeAtEnd());

            time_step_number++;

            // Determine what the value time step should really be like
            double to_time = start_time+time_step_number*timestep;

            if (to_time >= close_to_end_time)
            {
                real_time_step = end_time - current_time;
                //std::cout<<"TImes: " << timestep << " " << stepper.GetNextTimeStep() <<", difference = " << timestep - stepper.GetNextTimeStep()  << "\n";
                to_time = end_time;

                // Note that with non-constant timesteps, the final timestep can vary a lot (but not more than a normal sized timestep!).
                TS_ASSERT_DELTA(stepper.GetNextTimeStep(), timestep, timestep);
            }
            else
            {
                // Otherwise the GetNextTimeStep() returns the stored timestep,
                TS_ASSERT_EQUALS(stepper.GetNextTimeStep(),  timestep);

            }
            TS_ASSERT_DELTA(stepper.GetNextTimeStep(), real_time_step, DBL_EPSILON);
            TS_ASSERT_EQUALS(stepper.GetIdealTimeStep(), timestep);
            TS_ASSERT_EQUALS(stepper.GetTime(), current_time);
            TS_ASSERT_EQUALS(stepper.GetNextTime(), to_time);

            // Determine the new current time
            current_time = to_time;
            stepper.AdvanceOneTimeStep();

            TS_ASSERT_EQUALS(current_time, stepper.GetTime());
        }

        TS_ASSERT(stepper.IsTimeAtEnd());
        TS_ASSERT(stepper.GetTotalTimeStepsTaken()==time_step_number);

        //Stepper no longer allows increments beyond the end to be silently ignored
        TS_ASSERT_THROWS_THIS(stepper.AdvanceOneTimeStep(), "TimeStepper incremented beyond end time.");
    }
コード例 #8
0
void pgsTestSuite::test_object_variable(void)
{
	// A check is done when a pgsNumber is assigned to verify whether it is
	// a valid number. Default is an integer otherwise pgsReal must be
	// specified as second parameter of the constructor
	// pgsString does not perform any check but does not authorize arithmetic
	// on it even if it stores a number
	
	// Test string type
	{
		pgsString a(wxT("test"));
		TS_ASSERT(a.is_string() && !a.is_number() && !a.is_record());
		pgsString b(wxT("123456."));
		TS_ASSERT(b.is_string() && !b.is_number() && !b.is_record());
		pgsString c(wxT("423432"));
		TS_ASSERT(c.is_string() && !c.is_number() && !c.is_record());
		pgsString d(wxT("+.644e5"));
		TS_ASSERT(d.is_string() && !d.is_number() && !d.is_record());
		pgsString e(wxT("0x0"));
		TS_ASSERT(e.is_string() && !e.is_number() && !e.is_record());
	}

	// Test number type
	{
		pgsNumber a(wxT("123456."), pgsReal);
		TS_ASSERT(a.is_real() && !a.is_string() && !a.is_record());
		pgsNumber b(wxT("423432"));
		TS_ASSERT(b.is_integer() && !b.is_string() && !b.is_record());
		pgsNumber c(wxT("+.644e5"), pgsReal);
		TS_ASSERT(c.is_real() && !c.is_string() && !c.is_record());
	}

	// Test integers
	{
		for (int i = 1; i <= 100; i++)
		{
			// [1] Generate a random integer as a string
			wxString str_rnd;
			for (int j = 0; j < i; j++)
			{
				char c = rand() % 9 + 48;
				str_rnd << c;
			}
			
			// [2] Allocate a number and test type properties
			pgsNumber exp(str_rnd);
			TS_ASSERT(exp.value() == str_rnd);
			TS_ASSERT(exp.is_number() && !exp.is_string() && !exp.is_record());
			TS_ASSERT(exp.is_integer() && !exp.is_real());
			
			// [3] Test copy constructor
			pgsNumber copy(exp);
			TS_ASSERT(copy.value() == exp.value() && copy.is_integer());
			
			// [4] Test assignment operator
			exp = pgsNumber(wxT("1") + str_rnd, pgsReal);
			TS_ASSERT(exp.is_number() && !exp.is_string() && !exp.is_record());
			TS_ASSERT(!exp.is_integer() && exp.is_real());
		}
	}

	// Test reals
	{
		for (int i = 2; i <= 16; i++)
		{
			// [1] Generate a random real as a string
			wxString str_rnd;
			for (int j = 0; j < i / 2; j++)
			{
				char c = rand() % 9 + 48;
				str_rnd << c;
			}
			str_rnd << wxT(".");
			for (int j = 0; j < i / 2; j++)
			{
				char c = rand() % 9 + 48;
				str_rnd << c;
			}
			
			// [2] Allocate a number and test type properties
			pgsNumber exp(str_rnd, pgsReal);
			TS_ASSERT(exp.is_number() && !exp.is_string() && !exp.is_record());
			TS_ASSERT(!exp.is_integer() && exp.is_real());
			
			// [3] Test copy constructor
			pgsNumber copy(exp);
			TS_ASSERT(copy.value() == exp.value() && copy.is_real());
			
			// [4] Test assignment operator
			exp = pgsNumber(wxT("1") + str_rnd, pgsReal);
			TS_ASSERT(exp.is_number() && !exp.is_string() && !exp.is_record());
			TS_ASSERT(!exp.is_integer() && exp.is_real());
		}
	}

	// Test real
	{
		pgsNumber exp(wxT("+1.5e-300000000000657788"), pgsReal);
		TS_ASSERT(exp.is_real() && !exp.is_integer() && !exp.is_string());
	}

	// Test real
	{
		pgsNumber exp(wxT("-1.e+0"), pgsReal);
		TS_ASSERT(exp.is_real() && !exp.is_integer() && !exp.is_string());
	}

	// Test real
	{
		pgsNumber exp(wxT("+.0e-1"), pgsReal);
		TS_ASSERT(exp.is_real() && !exp.is_integer() && !exp.is_string());
	}

	// Test real
	{
		pgsNumber exp(wxT("-0.0E5"), pgsReal);
		TS_ASSERT(exp.is_real() && !exp.is_integer() && !exp.is_string());
	}

	// Test real
	{
		pgsNumber exp(wxT("0."), pgsReal);
		TS_ASSERT(exp.is_real() && !exp.is_integer() && !exp.is_string());
	}

	// Test real
	{
		pgsNumber exp(wxT(".1234567890098765432"), pgsReal);
		TS_ASSERT(exp.is_real() && !exp.is_integer() && !exp.is_string());
	}

	// Test string
	{
		pgsString exp(wxT("."));
		TS_ASSERT(!exp.is_real() && !exp.is_integer() && exp.is_string());
	}

	// Test string
	{
		pgsString exp(wxT(""));
		TS_ASSERT(!exp.is_real() && !exp.is_integer() && exp.is_string());
	}

	// Test string
	{
		pgsString exp(wxT("e5"));
		TS_ASSERT(!exp.is_real() && !exp.is_integer() && exp.is_string());
	}

	// Test real
	{
		pgsNumber exp(wxT("0e0"), pgsReal);
		TS_ASSERT(exp.is_real() && !exp.is_integer() && !exp.is_string());
	}

	// Test real
	{
		pgsNumber exp(wxT("100000000000000000e1"), pgsReal);
		TS_ASSERT(exp.is_real() && !exp.is_integer() && !exp.is_string());
	}

	// Test string
	{
		pgsString exp(wxT("100000000000000000e"));
		TS_ASSERT(!exp.is_real() && !exp.is_integer() && exp.is_string());
	}

	// Test some operations
	{
		pgsVariable * a = pnew pgsNumber(wxT("123."), pgsReal);
		pgsVariable * b = pnew pgsNumber(wxT("2"), pgsInt);
		pgsVariable * c = pnew pgsString(wxT("0x1"));
		
		pgsVarMap vars;
		
		// 123. + 2 gives 125
		pgsPlus * d = 0;
		d = pnew pgsPlus(a, b); // Deletes a and b		
		pgsOperand v = d->eval(vars);
		TS_ASSERT(v->value() == wxT("125") && v->is_real());
		
		// (123. + 2) + 0x1 gives the concatenation of the strings
		pgsPlus * e = 0;
		e = pnew pgsPlus(d, c); // Deletes d and c
		try
		{
			e->eval(vars);
			TS_ASSERT(false);
		}
		catch (const pgsArithmeticException &)
		{
			
		}
		
		// Test copy
		pgsPlus f(*e); // f is automatically deleted
		pdelete(e); // Deletes e
	}
}
コード例 #9
0
ファイル: vector.cpp プロジェクト: onitake/glam
	void testFeatures() {
		// is_pod requires non-trivial copy/move constructors and non-trivial copy/move assignment operators
		// since we already provide a const internal pointer accessor, we don't enforce this requirementi
		TS_ASSERT(std::is_standard_layout<glam::vec2>::value);
		TS_ASSERT(std::is_standard_layout<glam::vec3>::value);
		TS_ASSERT(std::is_standard_layout<glam::vec4>::value);
		TS_ASSERT(std::is_standard_layout<glam::ivec2>::value);
		TS_ASSERT(std::is_standard_layout<glam::ivec3>::value);
		TS_ASSERT(std::is_standard_layout<glam::ivec4>::value);
		TS_ASSERT(std::is_standard_layout<glam::dvec2>::value);
		TS_ASSERT(std::is_standard_layout<glam::dvec3>::value);
		TS_ASSERT(std::is_standard_layout<glam::dvec4>::value);
		TS_ASSERT(std::is_standard_layout<glam::bvec2>::value);
		TS_ASSERT(std::is_standard_layout<glam::bvec3>::value);
		TS_ASSERT(std::is_standard_layout<glam::bvec4>::value);
	}
コード例 #10
0
 void test_create() {
   TS_ASSERT(kind_of<Dir>(d));
 }
コード例 #11
0
        void test_insert()
        {
            Vector<int> v(9, 1);
            v.insert(0, 2);
            TS_ASSERT(v[0] == 2);
            for (unsigned int i = 1; i < v.size(); ++i)
                TS_ASSERT(v[i] == 1);
            v.insert(5, 3);
            TS_ASSERT(v[5] == 3);
            v.insert(10, 4);
            TS_ASSERT(v[10] == 4);

            Vector<int> w(5, 8);
            w.insert(4, 1);
            TS_ASSERT(w[4] == 1);
            for (unsigned int i = 0; i < w.size() - 2; ++i)
                TS_ASSERT(w[i] == 8);

            w.insert(w.size(), 33);
            TS_ASSERT(w[w.size()-1] == 33);

            Vector<int> v2;
            for (int i = 0; i < 3; ++i)
            {
                v2.insert(0, 42);
                v2.insert(0, -43);
                v2.insert(1, 44);
                v2.insert(3, 45);
            }
            for (int i = 0; i < 3; ++i)
            {
                TS_ASSERT(v2[i * 4] == -43);
                TS_ASSERT(v2[i * 4 + 1] == 44);
                TS_ASSERT(v2[i * 4 + 2] == 42);
                TS_ASSERT(v2[i * 4 + 3] == 45);
            }
        }
コード例 #12
0
ファイル: test_symbol.hpp プロジェクト: Locke23rus/rubinius
  void test_all_symbols() {
    Array* symbols = Symbol::all_symbols(state);

    TS_ASSERT(kind_of<Array>(symbols));
  }
コード例 #13
0
ファイル: test_symbol.hpp プロジェクト: Locke23rus/rubinius
 void test_to_str() {
   Symbol* sym = state->symbol("blah");
   String* str = sym->to_str(state);
   TS_ASSERT(!strncmp("blah", str->c_str(state), 4));
 }
コード例 #14
0
ファイル: test_io.hpp プロジェクト: leavengood/rubinius
 void test_force_write_only() {
   io->force_write_only(state);
   TS_ASSERT((io->mode()->to_native() & O_ACCMODE) == O_WRONLY);
 }
コード例 #15
0
void HdividerTests::testConcurrentReadInput()
    {
        map<InputId, int > *input_data = new map<InputId, int >;
        map<int, int> *result = new map<int, int>;
        
        int first_summ = 0;
        int first_elem_summ = 0;
        for (int i = 0; i<100; i++)
        {
                input_data->insert(pair<InputId, int>(i , i));
                
                if (i%2==0)
                {
                    first_summ +=2;
                }
                if (i%3==0)
                {
                    first_summ +=3;
                }
                if (i%5==0)
                {
                    first_summ += 5;
                }
                if (i%7==0)
                {
                    first_summ += 7;
                }
                first_elem_summ += i;
        }
        
        (*result)[2] = (*result)[3] = (*result)[5] = (*result)[7] = (*result)[9] = 0;
        
        HdividerWatcher* watcher = new HdividerWatcher(new HdividerTestInputIdIt (input_data), \
                new HdividerTestStateAccessor());
        
        int nthreads = 1000;
        vector<pthread_t> ths;
        
        for (int i = 0; i<nthreads; i++)
        {
            pthread_t th;
            char bf[10];
            sprintf(bf, "%d", i);
            string worker_id( "worker"+string(bf));
            
            worker_args2 *args1 = new worker_args2(new HdividerTestWorker(watcher), \
                input_data, result, worker_id, 0);
            pthread_create(&th, NULL, worker_func2, (void*)args1);
            ths.push_back(th);
        }
     
        for (int i = 0; i<nthreads; i++)
        {
                pthread_join(ths[i], NULL);
        }
        
        map<int, int>::iterator it = result->begin();
 
        int summ = 0;
        
        summ += (*result)[2] + (*result)[3] + (*result)[5] +(*result)[7];
        
        
        TS_ASSERT(first_summ == summ);
        cout << "first_summ: " << first_summ << endl;
        cout << "summ: " << summ << endl;
        
        // read test
        TS_ASSERT((*result)[9] == first_elem_summ);
        cout << "first_summ: " << first_elem_summ << endl;
        cout << "summ: " << (*result)[9] << endl;
    }
コード例 #16
0
ファイル: vector.cpp プロジェクト: onitake/glam
	void testVec5Equal() {
		glam::Vector<float, 5> v(1, 2, 3.5, 100, 0.00001);
		TS_ASSERT(v == v);
		TS_ASSERT(!(v != v));
		glam::Vector<float, 5> v2(1, 2, 3.5, 100, 0.00001);
		TS_ASSERT(v == v2);
		glam::Vector<float, 5> w(0, 2, 3.5, 200, 0.0001);
		TS_ASSERT(v != w);
		glam::Vector<float, 5> w1(1, 2, 3.5, 100, 0.00001);
		TS_ASSERT(glam::all(glam::equal(v, w1)));
		glam::Vector<float, 5> w2(1, 2, 3.5, 100, 0.0001);
		TS_ASSERT(!glam::all(glam::equal(v, w2)));
		TS_ASSERT(glam::any(glam::equal(v, w2)));
		glam::Vector<float, 5> w3(0, 0, 0, 0, 0);
		TS_ASSERT(!glam::all(glam::equal(v, w3)));
		TS_ASSERT(!glam::any(glam::equal(v, w3)));
		TS_ASSERT(glam::all(glam::notEqual(v, w3)));
		TS_ASSERT(glam::any(glam::notEqual(v, w3)));
		glam::Vector<float, 5> w4(0.0001, 100, 3.5, 2, 1);
		TS_ASSERT(!glam::all(glam::equal(v, w4)));
		TS_ASSERT(glam::any(glam::equal(v, w4)));
		TS_ASSERT(glam::any(glam::notEqual(v, w4)));
	}
コード例 #17
0
ファイル: test_channel.hpp プロジェクト: ConradIrwin/rubinius
 void test_create() {
   TS_ASSERT(kind_of<Channel>(chan));
 }
コード例 #18
0
ファイル: test_regexp.hpp プロジェクト: Azzurrio/rubinius
 void test_create() {
   Regexp* re = Regexp::create(state);
   TS_ASSERT(re->source()->nil_p());
   TS_ASSERT(re->names()->nil_p());
   TS_ASSERT_EQUALS(re->klass(), G(regexp));
 }
コード例 #19
0
// see #1061
    void Test3dBathExtracellularStimulusOneEdgeGroundedOnOppositeEdge()
    {
        HeartConfig::Instance()->SetSimulationDuration(6);  //ms
        HeartConfig::Instance()->SetOutputDirectory("BidomainBath3dExtraStimGrounded");
        HeartConfig::Instance()->SetOutputFilenamePrefix("bidomain_bath_3d");

        HeartConfig::Instance()->SetOdeTimeStep(0.005);  //ms

        // need to create a cell factory but don't want any intra stim, so magnitude
        // of stim is zero.
        c_vector<double,3> centre;
        centre(0) = 0.1;
        centre(1) = 0.1;
        centre(2) = 0.1;
        BathCellFactory<3> cell_factory( 0.0, centre);

        BidomainProblem<3> bidomain_problem( &cell_factory, true );

        TrianglesMeshReader<3,3> reader("mesh/test/data/cube_2mm_1016_elements");
        TetrahedralMesh<3,3> mesh;
        mesh.ConstructFromMeshReader(reader);

        // Set everything outside a central sphere (radius 0.4) to be bath
        for (unsigned i=0; i<mesh.GetNumElements(); i++)
        {
            double x = mesh.GetElement(i)->CalculateCentroid()[0];
            double y = mesh.GetElement(i)->CalculateCentroid()[1];
            double z = mesh.GetElement(i)->CalculateCentroid()[2];
            if (sqrt((x-0.1)*(x-0.1) + (y-0.1)*(y-0.1) + (z-0.1)*(z-0.1)) > 0.03)
            {
                mesh.GetElement(i)->SetAttribute(1);
            }
        }

        bidomain_problem.SetMesh(&mesh);

        //boundary flux for Phi_e
        double boundary_flux = -4e3;
        double duration = 2.5; //ms

        HeartConfig::Instance()->SetElectrodeParameters(true,0,boundary_flux, 0.0, duration);
        bidomain_problem.Initialise();
        bidomain_problem.Solve();

        Vec sol = bidomain_problem.GetSolution();
        ReplicatableVector sol_repl(sol);

        bool ap_triggered = false;

        for (unsigned i=0; i<mesh.GetNumNodes(); i++)
        {
            // test V = 0 for all bath nodes
            if (HeartRegionCode::IsRegionBath( mesh.GetNode(i)->GetRegion() )) // bath
            {
                TS_ASSERT_DELTA(sol_repl[2*i], 0.0, 1e-12);
            }
            else if (sol_repl[2*i] > 0.0)
            {
                ap_triggered = true;
            }
        }
        TS_ASSERT(ap_triggered);
    }
コード例 #20
0
 void test_create() {
   TS_ASSERT(kind_of<CompactLookupTable>(tbl));
   TS_ASSERT_EQUALS(tbl->num_fields(), (native_int)COMPACTLOOKUPTABLE_SIZE);
 }
コード例 #21
0
    void TestSolvePdeAndWriteResultsToFileWithCoarsePdeMesh() throw(Exception)
    {
        EXIT_IF_PARALLEL;

        // Set up SimulationTime
        SimulationTime::Instance()->SetEndTimeAndNumberOfTimeSteps(0.05, 6);

        // Create a cell population
        HoneycombMeshGenerator generator(5, 5, 0);
        MutableMesh<2,2>* p_mesh = generator.GetMesh();

        std::vector<CellPtr> cells;
        CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator;
        cells_generator.GenerateBasic(cells, p_mesh->GetNumNodes());

        MeshBasedCellPopulation<2> cell_population(*p_mesh, cells);

        // Create a PDE handler object using this cell population
        CellBasedPdeHandler<2> pde_handler(&cell_population);

        // Set up PDE and pass to handler
        AveragedSourcePde<2> pde(cell_population, -0.1);
        ConstBoundaryCondition<2> bc(1.0);
        PdeAndBoundaryConditions<2> pde_and_bc(&pde, &bc, false);
        pde_and_bc.SetDependentVariableName("quantity 1");
        pde_handler.AddPdeAndBc(&pde_and_bc);

        // Set up second PDE and pass to handler
        AveragedSourcePde<2> pde2(cell_population, -0.5);
        PdeAndBoundaryConditions<2> pde_and_bc2(&pde2, &bc, false);
        TS_ASSERT_THROWS_THIS(pde_handler.AddPdeAndBc(&pde_and_bc2), "When adding more than one PDE to CellBasedPdeHandler set the dependent variable name using SetDependentVariableName(name).");
        pde_and_bc2.SetDependentVariableName("quantity 1");
        TS_ASSERT_THROWS_THIS(pde_handler.AddPdeAndBc(&pde_and_bc2), "The name quantity 1 has already been used in the PDE collection");
        pde_and_bc2.SetDependentVariableName("quantity 2");
        pde_handler.AddPdeAndBc(&pde_and_bc2);

        // Solve PDEs on a coarse mesh
        ChastePoint<2> lower(0.0, 0.0);
        ChastePoint<2> upper(50.0, 50.0);
        ChasteCuboid<2> cuboid(lower, upper);
        pde_handler.UseCoarsePdeMesh(10.0, cuboid, true);
        pde_handler.SetImposeBcsOnCoarseBoundary(false);

        // Open result file ourselves
        OutputFileHandler output_file_handler("TestSolvePdeAndWriteResultsToFileWithCoarsePdeMesh", false);
        pde_handler.mpVizPdeSolutionResultsFile = output_file_handler.OpenOutputFile("results.vizpdesolution");

        // Solve PDEs and (for coverage) write results to file
        pde_handler.SolvePdeAndWriteResultsToFile(1);

        // Close result file ourselves
        pde_handler.mpVizPdeSolutionResultsFile->close();

        TetrahedralMesh<2,2>* p_coarse_mesh = pde_handler.GetCoarsePdeMesh();
        TS_ASSERT(p_coarse_mesh != NULL);

        TS_ASSERT_THROWS_THIS(pde_handler.GetPdeSolution("quantity 3"), "The PDE collection does not contain a PDE named quantity 3");
        ReplicatableVector pde_solution0(pde_handler.GetPdeSolution("quantity 1"));
        ReplicatableVector pde_solution1(pde_handler.GetPdeSolution("quantity 2"));

        TS_ASSERT_EQUALS(pde_solution0.GetSize(), pde_solution1.GetSize());

        // Test that the solution is 1.0 at each coarse mesh node far from the cells
        for (unsigned i=0; i<pde_solution0.GetSize(); i++)
        {
            c_vector<double,2> centre;
            centre(0) = 2.5; // assuming 5x5 honeycomb mesh
            centre(1) = 2.5;

            c_vector<double,2> position = p_coarse_mesh->GetNode(i)->rGetLocation();
            double dist = norm_2(centre - position);
            double u0 = pde_solution0[i];
            double u1 = pde_solution1[i];

            if (dist > 4.0)
            {
                TS_ASSERT_DELTA(u0, 1.0, 1e-5);
                TS_ASSERT_DELTA(u1, 1.0, 1e-5);
            }
        }

        /*
         * Loop over cells, find the coarse mesh element containing it, then
         * check the interpolated PDE solution is between the min and max of
         * the PDE solution on the nodes of that element.
         */
        for (AbstractCellPopulation<2>::Iterator cell_iter = cell_population.Begin();
            cell_iter != cell_population.End();
            ++cell_iter)
        {
            c_vector<double,2> cell_location = cell_population.GetLocationOfCellCentre(*cell_iter);

            unsigned elem_index = p_coarse_mesh->GetContainingElementIndex(cell_location);
            Element<2,2>* p_element = p_coarse_mesh->GetElement(elem_index);

            unsigned node_0_index = p_element->GetNodeGlobalIndex(0);
            unsigned node_1_index = p_element->GetNodeGlobalIndex(1);
            unsigned node_2_index = p_element->GetNodeGlobalIndex(2);

            double max0 = std::max(pde_solution0[node_0_index], pde_solution0[node_1_index]);
            max0 = std::max(max0, pde_solution0[node_2_index]);

            double max1 = std::max(pde_solution1[node_0_index], pde_solution1[node_1_index]);
            max1 = std::max(max1, pde_solution1[node_2_index]);

            double min0 = std::min(pde_solution0[node_0_index], pde_solution0[node_1_index]);
            min0 = std::min(min0, pde_solution0[node_2_index]);

            double min1 = std::min(pde_solution1[node_0_index], pde_solution1[node_1_index]);
            min1 = std::min(min1, pde_solution1[node_2_index]);

            double value0_at_cell = cell_iter->GetCellData()->GetItem("quantity 1");
            double value1_at_cell = cell_iter->GetCellData()->GetItem("quantity 2");

            TS_ASSERT_LESS_THAN_EQUALS(value1_at_cell, value0_at_cell);
            TS_ASSERT_LESS_THAN_EQUALS(min0, value0_at_cell + DBL_EPSILON);
            TS_ASSERT_LESS_THAN_EQUALS(value0_at_cell, max0 + DBL_EPSILON);
            TS_ASSERT_LESS_THAN_EQUALS(min1, value1_at_cell + DBL_EPSILON);
            TS_ASSERT_LESS_THAN_EQUALS(value1_at_cell, max1 + DBL_EPSILON);

            // Now check the GetPdeSolutionAtPoint method matches
            TS_ASSERT_DELTA(pde_handler.GetPdeSolutionAtPoint(cell_location, "quantity 1"), value0_at_cell, 1e-6);
            TS_ASSERT_DELTA(pde_handler.GetPdeSolutionAtPoint(cell_location, "quantity 2"), value1_at_cell, 1e-6);
        }
    }
コード例 #22
0
    void TestNodeBasedSimulationWithContactInhibition()
    {
        EXIT_IF_PARALLEL;    // HoneycombMeshGenerator does not work in parallel

        // Create a simple 2D NodeBasedCellPopulation
        HoneycombMeshGenerator generator(5, 5, 0);
        TetrahedralMesh<2,2>* p_generating_mesh = generator.GetMesh();
        NodesOnlyMesh<2> mesh;
        mesh.ConstructNodesWithoutMesh(*p_generating_mesh, 1.5);

        MAKE_PTR(WildTypeCellMutationState, p_state);
        MAKE_PTR(TransitCellProliferativeType, p_transit_type);
        std::vector<CellPtr> cells;
        for (unsigned i=0; i<mesh.GetNumNodes(); i++)
        {
            ContactInhibitionCellCycleModel* p_cycle_model = new ContactInhibitionCellCycleModel();
            p_cycle_model->SetDimension(2);
            p_cycle_model->SetBirthTime(-10.0);
            p_cycle_model->SetQuiescentVolumeFraction(0.9);
            p_cycle_model->SetEquilibriumVolume(0.7854); //pi *(0.5)^2
            p_cycle_model->SetStemCellG1Duration(0.1);
            p_cycle_model->SetTransitCellG1Duration(0.1);

            CellPtr p_cell(new Cell(p_state, p_cycle_model));
            p_cell->SetCellProliferativeType(p_transit_type);
            cells.push_back(p_cell);
        }

        NodeBasedCellPopulation<2> cell_population(mesh, cells);
        cell_population.AddPopulationWriter<CellMutationStatesCountWriter>();
        cell_population.AddCellWriter<CellVolumesWriter>();
        cell_population.AddPopulationWriter<NodeVelocityWriter>();

        // Create a simulation
        OffLatticeSimulation<2> simulator(cell_population);
        simulator.SetOutputDirectory("TestNodeBasedSimulationWithVolumeTracked");

        TS_ASSERT_EQUALS(simulator.GetDt(), 1.0/120.0); // Default value for off-lattice simulations
        simulator.SetEndTime(simulator.GetDt()/2.0);

        // Create a volume-tracking modifier and pass it to the simulation
        MAKE_PTR(VolumeTrackingModifier<2>, p_modifier);
        simulator.AddSimulationModifier(p_modifier);

        // Create a force law and pass it to the simulation
        MAKE_PTR(GeneralisedLinearSpringForce<2>, p_force);
        p_force->SetCutOffLength(1.5);
        simulator.AddForce(p_force);

        // Run simulation
        simulator.Solve();

        // Test that the node velocities file exists
        OutputFileHandler output_file_handler("TestNodeBasedSimulationWithVolumeTracked", false);
        FileFinder generated = output_file_handler.FindFile("results_from_time_0/nodevelocities.dat");
        TS_ASSERT(generated.Exists());

        // Test that the volumes of the cells are correct in CellData at the first timestep
        for (AbstractCellPopulation<2>::Iterator cell_iter = cell_population.Begin();
             cell_iter != cell_population.End();
             ++cell_iter)
        {
            TS_ASSERT_DELTA(cell_population.GetVolumeOfCell(*cell_iter), cell_iter->GetCellData()->GetItem("volume"), 1e-4);
        }

        simulator.SetEndTime(2.0);

        // Run simulation
        simulator.Solve();

        // Test that the volumes of the cells are correct in CellData at the end time
        for (AbstractCellPopulation<2>::Iterator cell_iter = cell_population.Begin();
             cell_iter != cell_population.End();
             ++cell_iter)
        {
            TS_ASSERT_DELTA(cell_population.GetVolumeOfCell(*cell_iter), cell_iter->GetCellData()->GetItem("volume"), 1e-4);
        }

        // Check that the correct number of cells are labelled (i.e. experiencing contact inhibition)
        TS_ASSERT_EQUALS(cell_population.GetCellPropertyRegistry()->Get<CellLabel>()->GetCellCount(), 2u);
    }
コード例 #23
0
    void TestWritingToFile() throw(Exception)
    {
        EXIT_IF_PARALLEL;

        std::string output_directory = "TestCellBasedPdeHandlerWritingToFile";

        // Create a cell population
        HoneycombMeshGenerator generator(4, 4, 0);
        MutableMesh<2,2>* p_generating_mesh = generator.GetMesh();
        NodesOnlyMesh<2> mesh;
        mesh.ConstructNodesWithoutMesh(*p_generating_mesh, 1.5);

        std::vector<CellPtr> cells;
        CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator;
        cells_generator.GenerateBasic(cells, mesh.GetNumNodes());
        TS_ASSERT_EQUALS(cells.size(), mesh.GetNumNodes());
        NodeBasedCellPopulation<2> cell_population(mesh, cells);

        cell_population.SetDataOnAllCells("variable", 1.0);

        // Create a PDE handler object using this cell population
        CellBasedPdeHandler<2> pde_handler(&cell_population);

        TS_ASSERT_THROWS_THIS(pde_handler.OpenResultsFiles(output_directory),
                "Trying to solve a PDE on a cell population that doesn't have a mesh. Try calling UseCoarsePdeMesh().");

        // Use a coarse PDE mesh since we are using a node-based cell population
        AveragedSourcePde<2> pde(cell_population, -0.1);
        ConstBoundaryCondition<2> bc(1.0);
        PdeAndBoundaryConditions<2> pde_and_bc(&pde, &bc, false);
        pde_and_bc.SetDependentVariableName("variable");
        pde_handler.AddPdeAndBc(&pde_and_bc);

        ChastePoint<2> lower(0.0, 0.0);
        ChastePoint<2> upper(9.0, 9.0);
        ChasteCuboid<2> cuboid(lower, upper);

        pde_handler.UseCoarsePdeMesh(3.0, cuboid, true);

        // For coverage, call SetWriteAverageRadialPdeSolution() prior to output
        pde_handler.SetWriteAverageRadialPdeSolution("variable", 5, true);

        // Test that output files are opened correctly
        pde_handler.OpenResultsFiles(output_directory);

        FileFinder file_finder(output_directory + "/results.vizcoarsepdesolution", RelativeTo::ChasteTestOutput);
        TS_ASSERT(file_finder.Exists());
        TS_ASSERT(file_finder.IsFile());

        FileFinder file_finder2(output_directory + "/radial_dist.dat", RelativeTo::ChasteTestOutput);
        TS_ASSERT(file_finder2.Exists());
        TS_ASSERT(file_finder2.IsFile());

        TS_ASSERT_THROWS_NOTHING(pde_handler.CloseResultsFiles());

        // For coverage, also test that output files are opened correctly when not using a coarse PDE mesh
        HoneycombMeshGenerator generator2(5, 5, 0);
        MutableMesh<2,2>* p_mesh2 = generator2.GetMesh();

        std::vector<CellPtr> cells2;
        CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator2;
        cells_generator2.GenerateBasic(cells2, p_mesh2->GetNumNodes());

        MeshBasedCellPopulation<2> cell_population2(*p_mesh2, cells2);

        cell_population2.SetDataOnAllCells("another variable", 1.0);

        CellBasedPdeHandler<2> pde_handler2(&cell_population2);
        pde_handler2.OpenResultsFiles(output_directory);

        FileFinder file_finder3(output_directory + "/results.vizpdesolution", RelativeTo::ChasteTestOutput);
        TS_ASSERT(file_finder3.Exists());
        TS_ASSERT(file_finder3.IsFile());

        pde_handler2.CloseResultsFiles();
    }
コード例 #24
0
    void TestPottsBasedWithCoarseMeshTwoEquations() throw(Exception)
    {
        EXIT_IF_PARALLEL;

        // Create a simple 2D PottsMesh
        PottsMeshGenerator<2> generator(6, 2, 2, 6, 2, 2);
        PottsMesh<2>* p_mesh = generator.GetMesh();

        // Create cells
        std::vector<CellPtr> cells;
        MAKE_PTR(DifferentiatedCellProliferativeType, p_diff_type);
        CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator;
        cells_generator.GenerateBasicRandom(cells, p_mesh->GetNumElements(), p_diff_type);

        // Create cell population
        PottsBasedCellPopulation<2> cell_population(*p_mesh, cells);

        // Set up cell-based simulation
        OnLatticeSimulation<2> simulator(cell_population);
        simulator.SetOutputDirectory("TestPottsBasedCellPopulationWithTwoPdes");
        simulator.SetEndTime(0.1);

        // Set up PDE and pass to simulation via handler (zero uptake to check analytic solution)
        AveragedSourcePde<2> pde_1(cell_population, 0.0);
        ConstBoundaryCondition<2> bc_1(1.0);
        PdeAndBoundaryConditions<2> pde_and_bc_1(&pde_1, &bc_1, false);
        pde_and_bc_1.SetDependentVariableName("quantity 1");

        AveragedSourcePde<2> pde_2(cell_population, 0.0);
        ConstBoundaryCondition<2> bc_2(1.0);
        PdeAndBoundaryConditions<2> pde_and_bc_2(&pde_2, &bc_2, false);
        pde_and_bc_2.SetDependentVariableName("quantity 2");

        CellBasedPdeHandler<2> pde_handler(&cell_population);
        pde_handler.AddPdeAndBc(&pde_and_bc_1);
        pde_handler.AddPdeAndBc(&pde_and_bc_2);
        ChastePoint<2> lower(0.0, 0.0);
        ChastePoint<2> upper(50.0, 50.0);
        ChasteCuboid<2> cuboid(lower, upper);
        pde_handler.UseCoarsePdeMesh(10.0, cuboid, true);
        pde_handler.SetImposeBcsOnCoarseBoundary(true);

        simulator.SetCellBasedPdeHandler(&pde_handler);

        // Create update rules and pass to the simulation
        MAKE_PTR(VolumeConstraintPottsUpdateRule<2>, p_volume_constraint_update_rule);
        simulator.AddPottsUpdateRule(p_volume_constraint_update_rule);
        MAKE_PTR(AdhesionPottsUpdateRule<2>, p_adhesion_update_rule);
        simulator.AddPottsUpdateRule(p_adhesion_update_rule);

        // Solve the system
        simulator.Solve();

        // Test solution is constant
        for (AbstractCellPopulation<2>::Iterator cell_iter = cell_population.Begin();
             cell_iter != cell_population.End();
             ++cell_iter)
        {
            double analytic_solution = 1.0;

            // Test that PDE solver is working correctly on both pdes
            TS_ASSERT_DELTA(cell_iter->GetCellData()->GetItem("quantity 1"), analytic_solution, 1e-2);
            TS_ASSERT_DELTA(cell_iter->GetCellData()->GetItem("quantity 2"), analytic_solution, 1e-2);
        }
#ifdef CHASTE_VTK
        //First file exists
        FileFinder vtk_file("TestPottsBasedCellPopulationWithTwoPdes/results_from_time_0/pde_results_1.vtu", RelativeTo::ChasteTestOutput);
        TS_ASSERT(vtk_file.Exists());
        // Check that the second VTK file for the solution has the dependent quantities
        OutputFileHandler handler("TestPottsBasedCellPopulationWithTwoPdes", false);
        VtkMeshReader<3,3> vtk_reader(handler.GetOutputDirectoryFullPath()+"results_from_time_0/pde_results_2.vtu");
        std::vector<double> data1;
        //There is no Oxygen
        TS_ASSERT_THROWS_CONTAINS(vtk_reader.GetPointData("Oxygen", data1), "No point data");
        TS_ASSERT(data1.empty());
        vtk_reader.GetPointData("quantity 1", data1);
        TS_ASSERT_EQUALS(data1.size(), 6u*6u);
        std::vector<double> data2;
        vtk_reader.GetPointData("quantity 2", data2);
        TS_ASSERT_EQUALS(data1.size(), data2.size());
#endif //CHASTE_VTK
    }
コード例 #25
0
    void TestWithCoarseContainedInFine() throw(Exception)
    {
        // Fine mesh is has h=0.1, on unit cube (so 6000 elements)
        TetrahedralMesh<3,3> fine_mesh;
        fine_mesh.ConstructRegularSlabMesh(0.1, 1.0, 1.0, 1.0);

        // Coarse mesh is has h=1 on unit cube (so 6 elements)
        QuadraticMesh<3> coarse_mesh(1.0, 1.0, 1.0, 1.0);

        FineCoarseMeshPair<3> mesh_pair(fine_mesh,coarse_mesh);

        mesh_pair.SetUpBoxesOnFineMesh(0.3);

        TS_ASSERT_EQUALS(mesh_pair.mpFineMeshBoxCollection->GetNumBoxes(), 4*4*4u);

        // For each node, find containing box. That box should contain any element that node is in.
        for (unsigned i=0; i<fine_mesh.GetNumNodes(); i++)
        {
            unsigned box_index = mesh_pair.mpFineMeshBoxCollection->CalculateContainingBox(fine_mesh.GetNode(i));

            assert(fine_mesh.GetNode(i)->rGetContainingElementIndices().size() > 0);

            for (std::set<unsigned>::iterator iter = fine_mesh.GetNode(i)->rGetContainingElementIndices().begin();
                iter != fine_mesh.GetNode(i)->rGetContainingElementIndices().end();
                ++iter)
            {
                Element<3,3>* p_element = fine_mesh.GetElement(*iter);
                TS_ASSERT_DIFFERS( mesh_pair.mpFineMeshBoxCollection->rGetBox(box_index).rGetElementsContained().find(p_element), mesh_pair.mpFineMeshBoxCollection->rGetBox(box_index).rGetElementsContained().end() )
            }
        }

        GaussianQuadratureRule<3> quad_rule(3);
        mesh_pair.ComputeFineElementsAndWeightsForCoarseQuadPoints(quad_rule, true);

        // All coarse quadrature points should have been found in the fine mesh
        TS_ASSERT_EQUALS(mesh_pair.mNotInMesh.size(), 0u);
        TS_ASSERT_EQUALS(mesh_pair.mNotInMeshNearestElementWeights.size(), 0u);

        // Check the elements and weights have been set up correctly
        // 6 elements, 8 quad points
        TS_ASSERT_EQUALS(mesh_pair.rGetElementsAndWeights().size(), 6*8u);

        // Some hardcoded values, just to check element_nums not all zero
        TS_ASSERT_EQUALS(mesh_pair.rGetElementsAndWeights()[0].ElementNum,  3816u);
        TS_ASSERT_EQUALS(mesh_pair.rGetElementsAndWeights()[10].ElementNum, 217u);
        TS_ASSERT_EQUALS(mesh_pair.rGetElementsAndWeights()[20].ElementNum, 1094u);

        for (unsigned i=0; i<mesh_pair.rGetElementsAndWeights().size(); i++)
        {
            TS_ASSERT_LESS_THAN(mesh_pair.rGetElementsAndWeights()[i].ElementNum, fine_mesh.GetNumElements());

            /*
             * As all the quadrature points should have been found in the fine mesh,
             * all the weights should be between 0 and 1.
             * Note weights = (1-psi_x-psi_y-psi_z, psi_x, psi_y, psi_z), where psi
             * is the position of the point in that element when transformed to the
             * canonical element.
             */
            for (unsigned j=0; j<4; j++)
            {
                TS_ASSERT_LESS_THAN(-1e14, mesh_pair.rGetElementsAndWeights()[i].Weights(j));
                TS_ASSERT_LESS_THAN(mesh_pair.rGetElementsAndWeights()[i].Weights(j), 1.0+1e-14);
            }
        }

        TS_ASSERT_EQUALS(mesh_pair.mStatisticsCounters[0], 6*8u);
        TS_ASSERT_EQUALS(mesh_pair.mStatisticsCounters[1], 0u);
        mesh_pair.PrintStatistics();

        mesh_pair.DeleteFineBoxCollection();
        TS_ASSERT(mesh_pair.mpFineMeshBoxCollection==NULL);
    }
コード例 #26
0
    void TestLuoRudyGeneralizedRushLarsenMethod()
    {
        EXIT_IF_PARALLEL;
        HeartConfig::Instance()->SetOdeTimeStep(0.01);
        GenerateCells();

        // Check the models really use Rush-Larsen
        TS_ASSERT_EQUALS(Warnings::Instance()->GetNumWarnings(), 0u);

        // Some coverage
        AbstractGeneralizedRushLarsenCardiacCell* p_grl_cell = dynamic_cast<AbstractGeneralizedRushLarsenCardiacCell*>(mpGeneralizedRushLarsenCell);
        TS_ASSERT(p_grl_cell);
        TS_ASSERT(!p_grl_cell->HasAnalyticJacobian());
        TS_ASSERT(!p_grl_cell->GetUseAnalyticJacobian());
        TS_ASSERT_THROWS_THIS(p_grl_cell->ForceUseOfNumericalJacobian(false),
                              "Using analytic Jacobian terms for generalised Rush-Larsen is not yet supported.");
        TS_ASSERT_THROWS_NOTHING(p_grl_cell->ForceUseOfNumericalJacobian(true));

        // Normal Luo-Rudy for comparison
        boost::shared_ptr<HeunIvpOdeSolver> p_heun_solver(new HeunIvpOdeSolver());
        CellLuoRudy1991FromCellML reference_model(p_heun_solver, mpGeneralizedRushLarsenCell->GetStimulusFunction());

        // Check GetIIonic is identical
        TS_ASSERT_DELTA(mpGeneralizedRushLarsenCell->GetIIonic(), reference_model.GetIIonic(), 1e-12);

        // Test non-stimulated cell (using ComputeExceptVoltage)
        mpGeneralizedRushLarsenCell->ComputeExceptVoltage(0.0, 1.0);
        reference_model.ComputeExceptVoltage(0.0, 1.0);

        TS_ASSERT_EQUALS(mpGeneralizedRushLarsenCell->GetNumberOfStateVariables(),
                         reference_model.GetNumberOfStateVariables());
        for (unsigned i=0; i<reference_model.GetNumberOfStateVariables(); i++)
        {
            TS_ASSERT_DELTA(mpGeneralizedRushLarsenCell->rGetStateVariables()[i],
                            reference_model.rGetStateVariables()[i], 1e-6);
        }

        // Test stimulated cell (using Compute)
        boost::shared_ptr<SimpleStimulus> p_stimulus(new SimpleStimulus(-25.5, 1.99, 0.0));
        mpGeneralizedRushLarsenCell->ResetToInitialConditions();
        mpGeneralizedRushLarsenCell->SetStimulusFunction(p_stimulus);
        OdeSolution solutions_GRL1 = mpGeneralizedRushLarsenCell->Compute(0.0, 1.0, 0.01);
        TS_ASSERT_EQUALS(solutions_GRL1.GetNumberOfTimeSteps(), 100u);

        reference_model.ResetToInitialConditions();
        reference_model.SetStimulusFunction(p_stimulus);
        OdeSolution solutions_ref = reference_model.Compute(0.0, 1.0, 0.01);

        for (unsigned i=0; i<reference_model.GetNumberOfStateVariables(); i++)
        {
            TS_ASSERT_DELTA(solutions_GRL1.rGetSolutions().back()[i],
                            solutions_ref.rGetSolutions().back()[i], 1e-2);
        }

        //Compare LuoRudy solution with general GRL1 solver solution (should match)
        mpGeneralizedRushLarsenCell->ResetToInitialConditions();
        boost::shared_ptr<ZeroStimulus> p_stimulus_zero(new ZeroStimulus());
        mpGeneralizedRushLarsenCell->SetStimulusFunction(p_stimulus_zero);
        mpGeneralizedRushLarsenCell->SetTimestep(1e-3);
        mpGeneralizedRushLarsenCell->SetVoltage(-30);
        OdeSolution solutions_GRL1_stimulated_cell_order1 = mpGeneralizedRushLarsenCell->Compute(0.0, 1e-3);

        // Compare with SolveAndUpdateState for coverage
        mpGeneralizedRushLarsenCell->ResetToInitialConditions();
        mpGeneralizedRushLarsenCell->SetVoltage(-30);
        mpGeneralizedRushLarsenCell->SolveAndUpdateState(0.0, 1e-3);
        for (unsigned i=0; i<mpGeneralizedRushLarsenCell->GetNumberOfStateVariables(); i++)
        {
            TS_ASSERT_DELTA(mpGeneralizedRushLarsenCell->rGetStateVariables()[i],
                            solutions_GRL1_stimulated_cell_order1.rGetSolutions().back()[i], 1e-12);
        }

        // Compare with general GRL1 method
        boost::shared_ptr<GRL1IvpOdeSolver> p_grl1_solver(new GRL1IvpOdeSolver());
        CellLuoRudy1991FromCellML reference_model_grl1(p_grl1_solver, mpGeneralizedRushLarsenCell->GetStimulusFunction());
        reference_model_grl1.ResetToInitialConditions();
        reference_model_grl1.SetStimulusFunction(p_stimulus_zero);
        reference_model_grl1.SetTimestep(1e-3);
        reference_model_grl1.SetVoltage(-30);
        OdeSolution ref_solution_grl1 = reference_model_grl1.Compute(0.0, 1e-3);

        for (unsigned i=0; i<reference_model_grl1.GetNumberOfStateVariables(); i++)
        {
            double error1 = solutions_GRL1_stimulated_cell_order1.rGetSolutions().back()[i] - ref_solution_grl1.rGetSolutions().back()[i];
            TS_ASSERT_DELTA(fabs(error1),0,5e-7);
        }

        // Test order of convergence (first-order method)

        // Get two solutions with halved stepsize
        mpGeneralizedRushLarsenCell->ResetToInitialConditions();
        reference_model_grl1.SetStimulusFunction(p_stimulus_zero);
        reference_model_grl1.SetVoltage(-30);
        mpGeneralizedRushLarsenCell->SetTimestep(0.002);
        solutions_GRL1_stimulated_cell_order1 = mpGeneralizedRushLarsenCell->Compute(0.0, 1.0);

        mpGeneralizedRushLarsenCell->ResetToInitialConditions();
        reference_model_grl1.SetStimulusFunction(p_stimulus_zero);
        reference_model_grl1.SetVoltage(-30);
        mpGeneralizedRushLarsenCell->SetTimestep(0.001);
        OdeSolution solutions_GRL1_stimulated_cell_order2 = mpGeneralizedRushLarsenCell->Compute(0.0, 1.0);

        // Get accurate solution to be used as reference solution
        //boost::shared_ptr<HeunIvpOdeSolver> p_heun_solver(new HeunIvpOdeSolver());
        reference_model.SetStimulusFunction(p_stimulus_zero);
        reference_model.SetVoltage(-30);
        reference_model.ResetToInitialConditions();
        reference_model.SetTimestep(1e-6);
        OdeSolution ref_solution = reference_model.Compute(0.0, 1.0);

        for (unsigned i=0; i<reference_model.GetNumberOfStateVariables(); i++)
        {
            double error1 = solutions_GRL1_stimulated_cell_order1.rGetSolutions().back()[i] - ref_solution.rGetSolutions().back()[i];
            double error2 = solutions_GRL1_stimulated_cell_order2.rGetSolutions().back()[i] - ref_solution.rGetSolutions().back()[i];
            TS_ASSERT_DELTA(error1/error2, 2, 0.1);
        }

        // Free memory
        delete mpGeneralizedRushLarsenCell;
//        delete mpGeneralizedRushLarsenCellOpt;
    }
コード例 #27
0
ファイル: test_gc_immix.hpp プロジェクト: AndrewVos/rubinius
 void test_Block_is_line_free() {
   immix::Block& block = gc->get_block();
   TS_ASSERT(block.is_line_free(1));
   block.mark_line(1);
   TS_ASSERT(!block.is_line_free(1));
 }
コード例 #28
0
 void test_create() {
   TS_ASSERT(kind_of<LookupTable>(tbl));
   TS_ASSERT_EQUALS(tbl-> bins()->to_native(), LOOKUPTABLE_MIN_SIZE);
 }
コード例 #29
0
    void test_init() {
        TS_ASSERT(G(selector)->kind_of_p(state, G(klass)));
        TS_ASSERT_EQUALS(G(selector)->instance_type()->to_native(), SelectorType);

        TS_ASSERT(G(selector)->get_const(state, "ALL")->kind_of_p(state, G(lookuptable)));
    }
コード例 #30
0
    void TestPrivateMethods()
    {
        // Set up a cell population
        HoneycombMeshGenerator mesh_generator(7, 5, 0, 2.0);
        MutableMesh<2,2>* p_mesh = mesh_generator.GetMesh();
        std::vector<unsigned> location_indices = mesh_generator.GetCellLocationIndices();

        CellsGenerator<FixedG1GenerationalCellCycleModel,2> cells_generator;
        std::vector<CellPtr> cells;
        cells_generator.GenerateGivenLocationIndices(cells, location_indices);

        MeshBasedCellPopulationWithGhostNodes<2> cell_population(*p_mesh, cells, location_indices);

        // Create the force law and pass in to a std::list
        MAKE_PTR(GeneralisedLinearSpringForce<2>, p_force);
        std::vector<boost::shared_ptr<AbstractTwoBodyInteractionForce<2> > > force_collection;
        force_collection.push_back(p_force);

        // Create a force calculator
        DiscreteSystemForceCalculator calculator(cell_population, force_collection);

        unsigned node_index = 8;

        // Test GetNeighbouringNodeIndices
        std::set<unsigned> expected_node_indices;
        expected_node_indices.insert(1u);
        expected_node_indices.insert(2u);
        expected_node_indices.insert(7u);
        expected_node_indices.insert(9u);
        expected_node_indices.insert(15u);
        expected_node_indices.insert(16u);

        std::set<unsigned> neighbouring_node_indices = cell_population.GetNeighbouringNodeIndices(node_index);

        TS_ASSERT(neighbouring_node_indices == expected_node_indices);

        // Test CalculateFtAndFn
        double spring_stiffness = p_force->GetMeinekeSpringStiffness();
        double expected_ft = spring_stiffness*(cos(M_PI/12.0) + cos(5.0*M_PI/12.0) - cos(3.0*M_PI/12.0));
        double expected_fn = spring_stiffness*(sin(M_PI/12.0) + sin(5.0*M_PI/12.0) + sin(3.0*M_PI/12.0));
        std::vector<double> Ft_and_Fn = calculator.CalculateFtAndFn(node_index,M_PI/4.0);
        TS_ASSERT_DELTA(Ft_and_Fn[0], expected_ft, 1e-4);
        TS_ASSERT_DELTA(Ft_and_Fn[1], expected_fn, 1e-4);

        // Test GetSamplingAngles
        std::vector<double> expected_sampling_angles;
        double epsilon = calculator.mEpsilon;

        expected_sampling_angles.push_back(-M_PI +epsilon);
        expected_sampling_angles.push_back(-M_PI +epsilon);

        for (unsigned i=1; i<6; i++)
        {
            expected_sampling_angles.push_back(-M_PI +((double) i)*M_PI/3.0 - epsilon);
            expected_sampling_angles.push_back(-M_PI +((double) i)*M_PI/3.0 - epsilon);
            expected_sampling_angles.push_back(-M_PI +((double) i)*M_PI/3.0 + epsilon);
            expected_sampling_angles.push_back(-M_PI +((double) i)*M_PI/3.0 + epsilon);
        }
        expected_sampling_angles.push_back(M_PI - epsilon);
        expected_sampling_angles.push_back(M_PI - epsilon);

        std::vector<double> sampling_angles = calculator.GetSamplingAngles(node_index);
        for (unsigned i=0; i<sampling_angles.size(); i++)
        {
            // the sampling angles lie in the range (pi,pi]
            if (expected_sampling_angles[i] > M_PI)
            {
                expected_sampling_angles[i] -= 2*M_PI;
            }

            TS_ASSERT_DELTA(sampling_angles[i], expected_sampling_angles[i], 1e-6);
        }

        // Test GetLocalExtremum
        double expected_extremal_angle = -M_PI +M_PI/6.0;
        double calculated_extremal_angle = calculator.GetLocalExtremum(node_index, sampling_angles[1], sampling_angles[2]);

        TS_ASSERT_DELTA(calculated_extremal_angle, expected_extremal_angle, 1e-4);

        // Test GetExtremalAngles
        std::vector<double> calculated_extremal_angles = calculator.GetExtremalAngles(node_index, sampling_angles);

        // the extremal angles lie in the range (pi,pi]
        TS_ASSERT_DELTA(-M_PI + M_PI/6.0, calculated_extremal_angles[0], 1e-4);
        TS_ASSERT_DELTA(-M_PI + M_PI/3.0, calculated_extremal_angles[1], 1e-4);
        TS_ASSERT_DELTA(-M_PI + M_PI/2.0, calculated_extremal_angles[2], 1e-4);
        TS_ASSERT_DELTA(-M_PI + 2.0*M_PI/3.0, calculated_extremal_angles[3], 1e-4);
        TS_ASSERT_DELTA(-M_PI + 5.0*M_PI/6.0, calculated_extremal_angles[4], 1e-4);
    }