void AbstractFeSurfaceIntegralAssembler<ELEMENT_DIM, SPACE_DIM, PROBLEM_DIM>::AssembleOnSurfaceElement(
            const BoundaryElement<ELEMENT_DIM-1,SPACE_DIM>& rSurfaceElement,
            c_vector<double, PROBLEM_DIM*ELEMENT_DIM>& rBSurfElem)
{
    c_vector<double, SPACE_DIM> weighted_direction;
    double jacobian_determinant;
    mpMesh->GetWeightedDirectionForBoundaryElement(rSurfaceElement.GetIndex(), weighted_direction, jacobian_determinant);

    rBSurfElem.clear();

    // Allocate memory for the basis function values
    c_vector<double, ELEMENT_DIM>  phi;

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

        SurfaceBasisFunction::ComputeBasisFunctions(quad_point, phi);

        //////////////////////////////
        // Interpolation: X only
        //////////////////////////////

        // The location of the Gauss point in the original element will be stored in x
        ChastePoint<SPACE_DIM> x(0,0,0);

        this->ResetInterpolatedQuantities();
        for (unsigned i=0; i<rSurfaceElement.GetNumNodes(); i++)
        {
            const c_vector<double, SPACE_DIM> node_loc = rSurfaceElement.GetNode(i)->rGetLocation();
            x.rGetLocation() += phi(i)*node_loc;

            // Allow the concrete version of the assembler to interpolate any desired quantities
            this->IncrementInterpolatedQuantities(phi(i), rSurfaceElement.GetNode(i));
        }


        //////////////////////////////////
        // Create elemental contribution
        //////////////////////////////////

        double wJ = jacobian_determinant * mpSurfaceQuadRule->GetWeight(quad_index);
        ///\todo #1321 Improve efficiency of Neumann BC implementation
        noalias(rBSurfElem) += ComputeVectorSurfaceTerm(rSurfaceElement, phi, x) * wJ;
    }
}
void ContinuumMechanicsNeumannBcsAssembler<DIM>::AssembleOnBoundaryElement(BoundaryElement<DIM-1,DIM>& rBoundaryElement,
                                                                           c_vector<double,STENCIL_SIZE>& rBelem,
                                                                           unsigned boundaryConditionIndex)
{
    rBelem.clear();

    c_vector<double, DIM> weighted_direction;
    double jacobian_determinant;
    mpMesh->GetWeightedDirectionForBoundaryElement(rBoundaryElement.GetIndex(), weighted_direction, jacobian_determinant);

    c_vector<double,NUM_NODES_PER_ELEMENT> phi;

    for (unsigned quad_index=0; quad_index<mpQuadRule->GetNumQuadPoints(); quad_index++)
    {
        double wJ = jacobian_determinant * mpQuadRule->GetWeight(quad_index);
        const ChastePoint<DIM-1>& quad_point = mpQuadRule->rGetQuadPoint(quad_index);
        QuadraticBasisFunction<DIM-1>::ComputeBasisFunctions(quad_point, phi);

        c_vector<double,DIM> traction = zero_vector<double>(DIM);
        switch (mpProblemDefinition->GetTractionBoundaryConditionType())
        {
            case ELEMENTWISE_TRACTION:
            {
                traction = mpProblemDefinition->rGetElementwiseTractions()[boundaryConditionIndex];
                break;
            }
            default:
                // Functional traction not implemented yet..
                NEVER_REACHED;
        }

        for (unsigned index=0; index<NUM_NODES_PER_ELEMENT*DIM; index++)
        {
            unsigned spatial_dim = index%DIM;
            unsigned node_index = (index-spatial_dim)/DIM;

            assert(node_index < NUM_NODES_PER_ELEMENT);

            rBelem(index) += traction(spatial_dim) * phi(node_index) * wJ;
        }
    }
}