void TestWithCoarseSlightlyOutsideFine() 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 slightly bigger than in previous test
        QuadraticMesh<3> coarse_mesh(1.0, 1.0, 1.0, 1.0); // xmax > 1.0
        coarse_mesh.Scale(1.03, 1.0, 1.0);

        FineCoarseMeshPair<3> mesh_pair(fine_mesh,coarse_mesh);

        GaussianQuadratureRule<3> quad_rule(3);

        // Need to call SetUpBoxesOnFineMesh first
        TS_ASSERT_THROWS_CONTAINS(mesh_pair.ComputeFineElementsAndWeightsForCoarseQuadPoints(quad_rule, true), "Call");

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

        mesh_pair.ComputeFineElementsAndWeightsForCoarseQuadPoints(quad_rule, true);

        TS_ASSERT_EQUALS(mesh_pair.mNotInMesh.size(), 2u); // hardcoded
        TS_ASSERT_EQUALS(mesh_pair.mNotInMeshNearestElementWeights.size(), 2u);

        TS_ASSERT_EQUALS(mesh_pair.rGetElementsAndWeights().size(), 6*8u);

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

            // comment out this test as now some of the weights are negative/greater than one
            //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);
            //}
        }

        /*
         * For each quadrature point that was not found in the fine mesh, check
         * that its x-value is greater than one - this is the only way it could
         * be outside the fine mesh.
         */
        QuadraturePointsGroup<3> quad_point_posns(coarse_mesh, quad_rule);
        for (unsigned i=0; i<mesh_pair.mNotInMesh.size(); i++)
        {
            double x = quad_point_posns.rGet(mesh_pair.mNotInMesh[i])(0);
            TS_ASSERT_LESS_THAN(1.0, x);
        }

        mesh_pair.PrintStatistics();

        TS_ASSERT_EQUALS( Warnings::Instance()->GetNumWarnings(), 1u);
        Warnings::Instance()->QuietDestroy();
    }
    /*
     * Test when calling ComputeFineElementsAndWeightsForCoarseQuadPoints()
     * in non-safe mode, but using the default value of box width. It is
     * difficult to get the class to run incorrectly (ie fail without an
     * assertion failing) in non-safe mode (ie we can't just specify boxes
     * that are too small), so we just test we get the same results as in
     * safe mode.
     */
    void TestNonSafeMode() 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);

        QuadraticMesh<3> coarse_mesh(1.0, 1.0, 1.0, 1.0); // xmax > 1.0
        coarse_mesh.Scale(1.03, 1.0, 1.0);

        FineCoarseMeshPair<3> mesh_pair(fine_mesh,coarse_mesh);
        GaussianQuadratureRule<3> quad_rule(3);

        // Call SetUpBoxesOnFineMesh() without providing a width
        mesh_pair.SetUpBoxesOnFineMesh();

        /*
         * Whereas before 4 by 4 by 4 boxes were explicitly chosen, here it
         * has been determined that 6 by 6 by 6 are needed.
         */
        TS_ASSERT_EQUALS(mesh_pair.mpFineMeshBoxCollection->GetNumBoxes(), 6*6*6u);

        mesh_pair.ComputeFineElementsAndWeightsForCoarseQuadPoints(quad_rule, false /* non-safe mode*/);

        TS_ASSERT_EQUALS(mesh_pair.mNotInMesh.size(), 2u); // hardcoded
        TS_ASSERT_EQUALS(mesh_pair.mNotInMeshNearestElementWeights.size(), 2u);
        TS_ASSERT_EQUALS(mesh_pair.rGetElementsAndWeights().size(), 6*8u);

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

        /*
         * For each quadrature point that was not found in the fine mesh, check
         * that its x-value is greater than one - this is the only way it could
         * be outside the fine mesh.
         */
        QuadraturePointsGroup<3> quad_point_posns(coarse_mesh, quad_rule);
        for (unsigned i=0; i<mesh_pair.mNotInMesh.size(); i++)
        {
            double x = quad_point_posns.rGet(mesh_pair.mNotInMesh[i])(0);
            TS_ASSERT_LESS_THAN(1.0, x);
        }

        mesh_pair.PrintStatistics();

        TS_ASSERT_EQUALS( Warnings::Instance()->GetNumWarnings(), 1u);
        Warnings::Instance()->QuietDestroy();
    }
    void TestLinearBasisFunction0d()
    {
        ChastePoint<0> zero;
        TS_ASSERT_DELTA(LinearBasisFunction<0>::ComputeBasisFunction(zero, 0), 1.0, 1e-12);

        c_vector<double, 1> basis_function_vector;
        LinearBasisFunction<0>::ComputeBasisFunctions(zero,basis_function_vector);
        TS_ASSERT_EQUALS(basis_function_vector.size(), 1u);
        TS_ASSERT_DELTA(basis_function_vector[0], 1.0, 1e-12);

        // Check link with 0d quad rule works ok
        GaussianQuadratureRule<0>  quad_rule(0);
        const ChastePoint<0>& quad_point = quad_rule.rGetQuadPoint(0);

        c_vector<double, 1> basis_function_vector2;
        LinearBasisFunction<0>::ComputeBasisFunctions(quad_point,basis_function_vector2);
        TS_ASSERT_EQUALS(basis_function_vector.size(), 1u);
        TS_ASSERT_DELTA(basis_function_vector[0], 1.0, 1e-12);
    }
    // Covers some bits that aren't covered in the tests above,
    void TestOtherCoverage() throw(Exception)
    {
        TetrahedralMesh<2,2> fine_mesh;
        fine_mesh.ConstructRegularSlabMesh(0.1, 1.0, 1.0);

        QuadraticMesh<2> coarse_mesh(1.0, 1.0, 1.0);

        /*
         * Rotate the mesh by 45 degrees, makes it possible (since boxes no
         * longer lined up with elements) for the containing element of a
         * quad point to be in a *local* box, ie not an element contained
         * in the box containing this point.
         */
        c_matrix<double,2,2> rotation_mat;
        rotation_mat(0,0) = 1.0/sqrt(2.0);
        rotation_mat(1,0) = -1.0/sqrt(2.0);
        rotation_mat(0,1) = 1.0/sqrt(2.0);
        rotation_mat(1,1) = 1.0/sqrt(2.0);

        fine_mesh.Rotate(rotation_mat);
        coarse_mesh.Rotate(rotation_mat);

        GaussianQuadratureRule<2> quad_rule(3);

        FineCoarseMeshPair<2> mesh_pair(fine_mesh,coarse_mesh);
        mesh_pair.SetUpBoxesOnFineMesh();
        mesh_pair.ComputeFineElementsAndWeightsForCoarseQuadPoints(quad_rule, true);
        TS_ASSERT_EQUALS(mesh_pair.mNotInMesh.size(), 0u);

        /*
         * Repeat again with smaller boxes, covers the bit requiring the whole
         * mesh to be searched to find an element for a particular quad point.
         */
        FineCoarseMeshPair<2> mesh_pair2(fine_mesh,coarse_mesh);
        mesh_pair2.SetUpBoxesOnFineMesh(0.01);
        mesh_pair2.ComputeFineElementsAndWeightsForCoarseQuadPoints(quad_rule, true);
        TS_ASSERT_EQUALS(mesh_pair.mNotInMesh.size(), 0u);
    }
    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);
    }
double AbstractFunctionalCalculator<ELEMENT_DIM, SPACE_DIM, PROBLEM_DIM>::CalculateOnElement(Element<ELEMENT_DIM, SPACE_DIM>& rElement)
{
    double result_on_element = 0;

    // Third order quadrature.  Note that the functional may be non-polynomial (see documentation of class).
    GaussianQuadratureRule<ELEMENT_DIM> quad_rule(3);

    /// NOTE: This assumes that the Jacobian is constant on an element, ie
    /// no curvilinear bases were used for position
    double jacobian_determinant;
    c_matrix<double, SPACE_DIM, ELEMENT_DIM> jacobian;
    c_matrix<double, ELEMENT_DIM, SPACE_DIM> inverse_jacobian;
    rElement.CalculateInverseJacobian(jacobian, jacobian_determinant, inverse_jacobian);

    const unsigned num_nodes = rElement.GetNumNodes();

    // Loop over Gauss points
    for (unsigned quad_index=0; quad_index < quad_rule.GetNumQuadPoints(); quad_index++)
    {
        const ChastePoint<ELEMENT_DIM>& quad_point = quad_rule.rGetQuadPoint(quad_index);

        c_vector<double, ELEMENT_DIM+1> phi;
        LinearBasisFunction<ELEMENT_DIM>::ComputeBasisFunctions(quad_point, phi);
        c_matrix<double, ELEMENT_DIM, ELEMENT_DIM+1> grad_phi;
        LinearBasisFunction<ELEMENT_DIM>::ComputeTransformedBasisFunctionDerivatives(quad_point, inverse_jacobian, grad_phi);

        // Location of the Gauss point in the original element will be stored in x
        ChastePoint<SPACE_DIM> x(0,0,0);
        c_vector<double,PROBLEM_DIM> u = zero_vector<double>(PROBLEM_DIM);
        c_matrix<double,PROBLEM_DIM,SPACE_DIM> grad_u = zero_matrix<double>(PROBLEM_DIM,SPACE_DIM);

        for (unsigned i=0; i<num_nodes; i++)
        {
            const c_vector<double, SPACE_DIM>& r_node_loc = rElement.GetNode(i)->rGetLocation();

            // Interpolate x
            x.rGetLocation() += phi(i)*r_node_loc;

            // Interpolate u and grad u
            unsigned node_global_index = rElement.GetNodeGlobalIndex(i);
            for (unsigned index_of_unknown=0; index_of_unknown<PROBLEM_DIM; index_of_unknown++)
            {
                // NOTE - following assumes that, if say there are two unknowns u and v, they
                // are stored in the current solution vector as
                // [U1 V1 U2 V2 ... U_n V_n]
                unsigned index_into_vec = PROBLEM_DIM*node_global_index + index_of_unknown;

                double u_at_node = mSolutionReplicated[index_into_vec];
                u(index_of_unknown) += phi(i)*u_at_node;
                for (unsigned j=0; j<SPACE_DIM; j++)
                {
                    grad_u(index_of_unknown,j) += grad_phi(j,i)*u_at_node;
                }
            }
        }

        double wJ = jacobian_determinant * quad_rule.GetWeight(quad_index);
        result_on_element += GetIntegrand(x, u, grad_u) * wJ;
    }

    return result_on_element;
}