void SideQuadPointsToSideInterpolationBase<EvalT, Traits, ScalarT>::evaluateFields (typename Traits::EvalData workset)
{
  // Note: since only required sides are processed by the evaluator,
  //       if we don't zero out the values from the previous workset
  //       we may save this field using old values and make a mess!

  ScalarT zero = 0.;
  field_side.deep_copy (zero);

  if (workset.sideSets->find(sideSetName)==workset.sideSets->end())
    return;

  const std::vector<Albany::SideStruct>& sideSet = workset.sideSets->at(sideSetName);
  for (auto const& it_side : sideSet)
  {
    // Get the local data of side and cell
    const int cell = it_side.elem_LID;
    const int side = it_side.side_local_id;

    MeshScalarT meas = 0.0;
    for (int qp(0); qp<dims[2]; ++qp)
    {
      meas += w_measure(cell,side,qp);
    }

    switch (fieldDim)
    {
      case 0:
        field_side(cell,side) = 0.0;
        for (int qp(0); qp<dims[2]; ++qp)
          field_side(cell,side) += field_qp(cell,side,qp)*w_measure(cell,side,qp);
        field_side(cell,side) /= meas;
        break;

      case 1:
        for (int i(0); i<dims[3]; ++i)
        {
          field_side(cell,side,i) = 0;
          for (int qp(0); qp<dims[2]; ++qp)
            field_side(cell,side,i) += field_qp(cell,side,qp,i)*w_measure(cell,side,qp);
          field_side(cell,side,i) /= meas;
        }
        break;

      case 2:
        for (int i(0); i<dims[3]; ++i)
        {
          for (int j(0); j<dims[4]; ++j)
          {
            field_side(cell,side,i,j) = 0;
            for (int qp(0); qp<dims[2]; ++qp)
              field_side(cell,side,i,j) += field_qp(cell,side,qp,i,j)*w_measure(cell,side,qp);
            field_side(cell,side,i,j) /= meas;
          }
        }
        break;

      default:
        TEUCHOS_TEST_FOR_EXCEPTION (true, std::logic_error, "Error! Field dimension not supported (this error should have already appeared).\n");
    }
  }
}
  void BasalFrictionHeat<EvalT,Traits,Type>::
  evaluateFields(typename Traits::EvalData d)
  {
    // Zero out, to avoid leaving stuff from previous workset!
    for (int cell = 0; cell < d.numCells; ++cell)
      for (int node = 0; node < numCellNodes; ++node)
        basalFricHeat(cell,node) = 0.;

    const double scyr (3.1536e7);  // [s/yr];

    if (d.sideSets->find(basalSideName)==d.sideSets->end())
      return;

    const std::vector<Albany::SideStruct>& sideSet = d.sideSets->at(basalSideName);

    for (auto const& it_side : sideSet)
    {
      // Get the local data of side and cell
      const int cell = it_side.elem_LID;
      const int side = it_side.side_local_id;

      for (int node = 0; node < numSideNodes; ++node)
      {
        basalFricHeat(cell,sideNodes[side][node]) = 0.;
        for (int qp = 0; qp < numSideQPs; ++qp)
        {
          for (int dim = 0; dim < vecDimFO; ++dim)
          {
            basalFricHeat(cell,sideNodes[side][node]) += 1000/scyr * beta(cell,side,qp) * velocity(cell,side,qp,dim) * velocity(cell,side,qp,dim) *
                BF(cell,side,node,qp) * w_measure(cell,side,qp);
          }
        }
      }
    }

    if (haveSUPG)
    {
      ScalarT wSUPG;

      // Zero out, to avoid leaving stuff from previous workset!
      for (int cell = 0; cell < d.numCells; ++cell)
        for (int node = 0; node < numCellNodes; ++node)
          basalFricHeatSUPG(cell,node) = 0.;

      const std::vector<Albany::SideStruct>& sideSetSUPG = d.sideSets->at(basalSideName);

      for (auto const& iter_side : sideSetSUPG)
      {
        // Get the local data of side and cell
        const int cell = iter_side.elem_LID;
        const int side = iter_side.side_local_id;

        for (int node = 0; node < numSideNodes; ++node)
        {
          basalFricHeatSUPG(cell,sideNodes[side][node]) = 0.;
          for (int qp = 0; qp < numSideQPs; ++qp)
          {
            wSUPG = 0.001 / scyr * // [km^2 s^{-1}]  TODO:check dimension
                (velocity(cell,side,qp,0)*GradBF(cell,side,node,qp,0) + velocity(cell,side,qp,1)*GradBF(cell,side,node,qp,1))*w_measure(cell,side,qp);

            basalFricHeatSUPG(cell,sideNodes[side][node]) += 1000 / scyr * beta(cell,side,qp) *
                (velocity(cell,side,qp,0) * velocity(cell,side,qp,0) + velocity(cell,side,qp,1) * velocity(cell,side,qp,1)) * wSUPG;
          }
        }
      }
    }
  }