Basis_HGRAD_QUAD_Cn_FEM<Scalar,ArrayScalar>::Basis_HGRAD_QUAD_Cn_FEM( const int order,
									const EPointType &pointType ):
    ptsx_( order+1 , 1 ) ,
    ptsy_( order+1 , 1 )
  {
    Array<Array<RCP<Basis<Scalar,ArrayScalar> > > > bases(1);
    bases[0].resize(2);
    bases[0][0] = Teuchos::rcp( new Basis_HGRAD_LINE_Cn_FEM<Scalar,ArrayScalar>( order , pointType ) );
    bases[0][1] = Teuchos::rcp( new Basis_HGRAD_LINE_Cn_FEM<Scalar,ArrayScalar>( order , pointType ) );
    this->setBases( bases );

    this->basisCardinality_ = (order+1)*(order+1);
    this->basisDegree_ = order;
    this -> basisCellTopology_ = shards::CellTopology(shards::getCellTopologyData<shards::Quadrilateral<4> >() );
    this -> basisType_         = BASIS_FEM_FIAT;
    this -> basisCoordinates_  = COORDINATES_CARTESIAN;
    this -> basisTagsAreSet_   = false;

    // fill up the pt arrays with calls to the lattice
    EPointType pt = (pointType==POINTTYPE_EQUISPACED)?pointType:POINTTYPE_WARPBLEND;
    PointTools::getLattice<Scalar,ArrayScalar >( ptsx_ ,
							    shards::CellTopology(shards::getCellTopologyData<shards::Line<2> >()) ,
							    order ,
							    0 ,
							    pt );
	  
    for (int i=0;i<order+1;i++)
      {
	ptsy_(i,0) = ptsx_(i,0);
      }

    initializeTags();
    this->basisTagsAreSet_ = true;
  }
  Basis_HGRAD_QUAD_Cn_FEM<Scalar,ArrayScalar>::Basis_HGRAD_QUAD_Cn_FEM( const int orderx , const int ordery,
									const ArrayScalar &pts_x ,
									const ArrayScalar &pts_y ): 
    ptsx_( pts_x.dimension(0) , 1 ) ,
    ptsy_( pts_y.dimension(0) , 1 )
  {
    Array<Array<RCP<Basis<Scalar,ArrayScalar> > > > bases(1);
    bases[0].resize(2);
    bases[0][0] = Teuchos::rcp( new Basis_HGRAD_LINE_Cn_FEM<Scalar,ArrayScalar>( orderx , pts_x ) );
    bases[0][1] = Teuchos::rcp( new Basis_HGRAD_LINE_Cn_FEM<Scalar,ArrayScalar>( ordery , pts_y ) );
    this->setBases( bases );

    this->basisCardinality_ = (orderx+1)*(ordery+1);
    if (orderx > ordery) {
      this->basisDegree_ = orderx;
    }
    else {
      this->basisDegree_ = ordery;
    }
    this -> basisCellTopology_ = shards::CellTopology(shards::getCellTopologyData<shards::Quadrilateral<4> >() );
    this -> basisType_         = BASIS_FEM_FIAT;
    this -> basisCoordinates_  = COORDINATES_CARTESIAN;
    this -> basisTagsAreSet_   = false;

    for (int i=0;i<pts_x.dimension(0);i++)
      {
	ptsx_(i,0) = pts_x(i,0);
      }

    for (int i=0;i<pts_y.dimension(0);i++)
      {
	ptsy_(i,0) = pts_y(i,0);
      }

  }
  Basis_HGRAD_HEX_Cn_FEM<Scalar,ArrayScalar>::Basis_HGRAD_HEX_Cn_FEM( const int order , 
								      const EPointType & pointType ):
    ptsx_( order+1 , 1 ),
    ptsy_( order+1 , 1 ),
    ptsz_( order+1 , 1 )
  {
    Array<Array<RCP<Basis<Scalar,ArrayScalar> > > > bases(1);
    bases[0].resize(3);

    bases[0][0] = Teuchos::rcp( new Basis_HGRAD_LINE_Cn_FEM< Scalar , ArrayScalar >( order , pointType ) );
    // basis is same in each direction, so I only need to instantiate it once!
    bases[0][1] = bases[0][0];
    bases[0][2] = bases[0][0];

    this->setBases( bases );

    this->basisCardinality_ = (order+1)*(order+1)*(order+1);
    this->basisDegree_ = order;
    this -> basisCellTopology_ = shards::CellTopology(shards::getCellTopologyData<shards::Hexahedron<8> >() );
    this -> basisType_         = BASIS_FEM_FIAT;
    this -> basisCoordinates_  = COORDINATES_CARTESIAN;
    this -> basisTagsAreSet_   = false;

    // get points
    EPointType pt = (pointType==POINTTYPE_EQUISPACED)?pointType:POINTTYPE_WARPBLEND;
    PointTools::getLattice<Scalar,ArrayScalar >( ptsx_ ,
							    shards::CellTopology(shards::getCellTopologyData<shards::Line<2> >()) ,
							    order ,
							    0 ,
							    pt );
    for (int i=0;i<order+1;i++)
      {
	ptsy_(i,0) = ptsx_(i,0);
	ptsz_(i,0) = ptsx_(i,0);
      }

    initializeTags();
    this->basisTagsAreSet_ = true;
  }
  void Basis_HGRAD_QUAD_Cn_FEM<Scalar, ArrayScalar>::getDofCoords( ArrayScalar & dofCoords ) const
  {
    int cur = 0;
    for (int j=0;j<ptsy_.dimension(0);j++)
      {
	for (int i=0;i<ptsx_.dimension(0);i++)
	  {
	    dofCoords(cur,0) = ptsx_(i,0);
	    dofCoords(cur,1) = ptsy_(j,0);
	    cur++;
	  }
      }
  }
  Basis_HGRAD_HEX_Cn_FEM<Scalar,ArrayScalar>::Basis_HGRAD_HEX_Cn_FEM( const int orderx , 
								      const int ordery ,
								      const int orderz ,
								      const ArrayScalar &pts_x ,
								      const ArrayScalar &pts_y ,
								      const ArrayScalar &pts_z ):
    ptsx_( pts_x.dimension(0) , 1 ),
    ptsy_( pts_y.dimension(0) , 1 ),
    ptsz_( pts_z.dimension(0) , 1 )
  {
    for (int i=0;i<pts_x.dimension(0);i++)
      {
	ptsx_(i,0) = pts_x(i,0);
      }
    for (int i=0;i<pts_y.dimension(0);i++)
      {
	ptsy_(i,0) = pts_y(i,0);
      }
    for (int i=0;i<pts_z.dimension(0);i++)
      {
	ptsz_(i,0) = pts_z(i,0);
      }

    Array<Array<RCP<Basis<Scalar,ArrayScalar> > > > bases(1);
    bases[0].resize(3);

    bases[0][0] = Teuchos::rcp( new Basis_HGRAD_LINE_Cn_FEM< Scalar , ArrayScalar >( orderx , pts_x ) );
    bases[0][1] = Teuchos::rcp( new Basis_HGRAD_LINE_Cn_FEM< Scalar , ArrayScalar >( ordery , pts_y ) );
    bases[0][2] = Teuchos::rcp( new Basis_HGRAD_LINE_Cn_FEM< Scalar , ArrayScalar >( orderz , pts_z ) );

    this->setBases( bases );

    this->basisCardinality_ = (orderx+1)*(ordery+1)*(orderz+1);
    if (orderx >= ordery && orderx >= orderz ) {
      this->basisDegree_ = orderx;
    }
    else if (ordery >= orderx && ordery >= orderz) {
      this->basisDegree_ = ordery;
    }
    else {
      this->basisDegree_ = orderz;
    }
    this -> basisCellTopology_ = shards::CellTopology(shards::getCellTopologyData<shards::Hexahedron<8> >() );
    this -> basisType_         = BASIS_FEM_FIAT;
    this -> basisCoordinates_  = COORDINATES_CARTESIAN;
    this -> basisTagsAreSet_   = false;

    initializeTags();
    this->basisTagsAreSet_ = true;
  }