void panzer::ProjectToEdges<EvalT, Traits>::
evaluateFields(typename Traits::EvalData workset)
{ 
  const shards::CellTopology & parentCell = *basis->getCellTopology();
  const int intDegree = basis->order();
  TEUCHOS_ASSERT(intDegree == 1);
  Intrepid2::DefaultCubatureFactory<double,Kokkos::DynRankView<double,PHX::Device>,Kokkos::DynRankView<double,PHX::Device>> quadFactory;
  Teuchos::RCP< Intrepid2::Cubature<double,Kokkos::DynRankView<double,PHX::Device>,Kokkos::DynRankView<double,PHX::Device>> > edgeQuad;

  // Collect the reference edge information. For now, do nothing with the quadPts.
  const unsigned num_edges = parentCell.getEdgeCount();
  std::vector<double> refEdgeWt(num_edges, 0.0);
  for (unsigned e=0; e<num_edges; e++) {
    edgeQuad = quadFactory.create(parentCell.getCellTopologyData(1,e), intDegree);
    const int numQPoints = edgeQuad->getNumPoints();
    Kokkos::DynRankView<double,PHX::Device> quadWts("quadWts",numQPoints);
    Kokkos::DynRankView<double,PHX::Device> quadPts("quadPts",numQPoints,num_dim);
    edgeQuad->getCubature(quadPts,quadWts);
    for (int q=0; q<numQPoints; q++)
      refEdgeWt[e] += quadWts(q);
  }

  // Loop over the edges of the workset cells.
  for (index_t cell = 0; cell < workset.num_cells; ++cell) {
    for (int p = 0; p < num_pts; ++p) {
      result(cell,p) = ScalarT(0.0);
      for (int dim = 0; dim < num_dim; ++dim)
        result(cell,p) += vector_values(cell,p,dim) * tangents(cell,p,dim);
      result(cell,p) *= refEdgeWt[p];
    }
  }

}
void CubatureControlVolume<Scalar,ArrayPoint,ArrayWeight>::getCubature(ArrayPoint& cubPoints,
		                                                       ArrayWeight& cubWeights,
                                                                       ArrayPoint& cellCoords) const
{
  // get array dimensions
  int numCells         = cellCoords.dimension(0);
  int numNodesPerCell  = cellCoords.dimension(1);
  int spaceDim         = cellCoords.dimension(2);
  int numNodesPerSubCV = subCVCellTopo_->getNodeCount();

  // get sub-control volume coordinates (one sub-control volume per node of primary cell)
  Intrepid2::FieldContainer<Scalar> subCVCoords(numCells,numNodesPerCell,numNodesPerSubCV,spaceDim);
  Intrepid2::CellTools<Scalar>::getSubCVCoords(subCVCoords,cellCoords,*(primaryCellTopo_));

  // Integration points and weights for calculating sub-control volumes
  Intrepid2::DefaultCubatureFactory<double>  subCVCubFactory;
  int subcvCubDegree = 2;
  Teuchos::RCP<Intrepid2::Cubature<double,Intrepid2::FieldContainer<double>  > > subCVCubature;
  subCVCubature = subCVCubFactory.create(*(subCVCellTopo_), subcvCubDegree);

  int subcvCubDim       = subCVCubature -> getDimension();
  int numSubcvCubPoints = subCVCubature -> getNumPoints();

   // Get numerical integration points and weights
  Intrepid2::FieldContainer<double> subcvCubPoints (numSubcvCubPoints, subcvCubDim);
  Intrepid2::FieldContainer<double> subcvCubWeights(numSubcvCubPoints);

  subCVCubature -> getCubature(subcvCubPoints, subcvCubWeights);

  // Loop over cells
  for (std::size_t icell = 0; icell < numCells; icell++){

    // get sub-control volume centers (integration points)
     Intrepid2::FieldContainer<Scalar> subCVCenter(numNodesPerCell,1,spaceDim);
     Intrepid2::FieldContainer<Scalar> cellCVCoords(numNodesPerCell,numNodesPerSubCV,spaceDim);
     for (int isubcv = 0; isubcv < numNodesPerCell; isubcv++){
       for (int idim = 0; idim < spaceDim; idim++){
          for (int inode = 0; inode < numNodesPerSubCV; inode++){
              subCVCenter(isubcv,0,idim) += subCVCoords(icell,isubcv,inode,idim)/numNodesPerSubCV;
              cellCVCoords(isubcv,inode,idim) = subCVCoords(icell,isubcv,inode,idim);
          }
          cubPoints(icell,isubcv,idim) = subCVCenter(isubcv,0,idim);
        }
     }

   // calculate Jacobian and determinant for each subCV quadrature point
     Intrepid2::FieldContainer<Scalar> subCVJacobian(numNodesPerCell, numSubcvCubPoints, spaceDim, spaceDim);
     Intrepid2::FieldContainer<Scalar> subCVJacobDet(numNodesPerCell, numSubcvCubPoints);
     Intrepid2::CellTools<Scalar>::setJacobian(subCVJacobian, subcvCubPoints, cellCVCoords, *(subCVCellTopo_));
     Intrepid2::CellTools<Scalar>::setJacobianDet(subCVJacobDet, subCVJacobian );

    // fill array with sub control volumes (the sub control volume cell measure)
     for (int inode = 0; inode < numNodesPerCell; inode++){
         Scalar vol = 0;
         for (int ipt = 0; ipt < numSubcvCubPoints; ipt++){
            vol += subcvCubWeights(ipt)*subCVJacobDet(inode,ipt);
         }
         cubWeights(icell,inode) = vol;
     }

 } // end cell loop

} // end getCubature