Real FE<1,CLOUGH>::shape(const Elem* elem,
			     const Order order,
			     const unsigned int i,
			     const Point& p)
{
  libmesh_assert(elem);

  clough_compute_coefs(elem);

  const ElemType type = elem->type();

  const Order totalorder = static_cast<Order>(order + elem->p_level());

  switch (totalorder)
    {
      // 3rd-order C1 cubic element
    case THIRD:
      {
	switch (type)
	  {
	    // C1 functions on the C1 cubic edge
	  case EDGE2:
	  case EDGE3:
	    {
	      libmesh_assert_less (i, 4);

	      switch (i)
		{
		case 0:
		  return clough_raw_shape(0, p);
		case 1:
		  return clough_raw_shape(1, p);
		case 2:
		  return d1xd1x * clough_raw_shape(2, p);
		case 3:
                  return d2xd2x * clough_raw_shape(3, p);
		default:
		  libmesh_error();
		}
	    }
	  default:
            libMesh::err << "ERROR: Unsupported element type!" << std::endl;
	    libmesh_error();
	  }
      }
      // by default throw an error
    default:
      libMesh::err << "ERROR: Unsupported polynomial order!" << std::endl;
      libmesh_error();
    }

  libmesh_error();
  return 0.;
}
Real FE<1,CLOUGH>::shape_second_deriv(const Elem* elem,
                                      const Order order,
                                      const unsigned int i,
                                      const unsigned int j,
                                      const Point& p)
{
  libmesh_assert(elem);

  clough_compute_coefs(elem);

  const ElemType type = elem->type();

  const Order totalorder = static_cast<Order>(order + elem->p_level());

  switch (totalorder)
    {
      // 3rd-order C1 cubic element
    case THIRD:
      {
        switch (type)
          {
            // C1 functions on the C1 cubic edge
          case EDGE2:
          case EDGE3:
            {
              switch (i)
                {
                case 0:
                  return clough_raw_shape_second_deriv(0, j, p);
                case 1:
                  return clough_raw_shape_second_deriv(1, j, p);
                case 2:
                  return d1xd1x * clough_raw_shape_second_deriv(2, j, p);
                case 3:
                  return d2xd2x * clough_raw_shape_second_deriv(3, j, p);
                default:
                  libmesh_error_msg("Invalid shape function index i = " << i);
                }
            }
          default:
            libmesh_error_msg("ERROR: Unsupported element type = " << type);
          }
      }
      // by default throw an error
    default:
      libmesh_error_msg("ERROR: Unsupported polynomial order = " << totalorder);
    }

  libmesh_error_msg("We'll never get here!");
  return 0.;
}