示例#1
0
void TLElasResid<EvalT, Traits>::
evaluateFields(typename Traits::EvalData workset)
{
  std::cout.precision(15);
  typedef Intrepid2::FunctionSpaceTools<PHX::Device> FST;
  typedef Intrepid2::RealSpaceTools<PHX::Device> RST;

  // using AD gives us P directly, we don't need to transform it
  if (matModel == "Neohookean AD")
  {
    for (int cell=0; cell < workset.numCells; ++cell) {
      for (int node=0; node < numNodes; ++node) {
	for (int dim=0; dim<numDims; dim++)  Residual(cell,node,dim)=0.0;
	for (int qp=0; qp < numQPs; ++qp) {
	  for (int i=0; i<numDims; i++) {
	    for (int j=0; j<numDims; j++) {
	      Residual(cell,node,i) += stress(cell, qp, i, j) * wGradBF(cell, node, qp, j);
	    } 
	  } 
	} 
      } 
    }
  }
  else
  {
    RST::inverse(F_inv, defgrad.get_view());
    RST::transpose(F_invT, F_inv);
    FST::scalarMultiplyDataData(JF_invT, J.get_view(), F_invT);
    FST::tensorMultiplyDataData(P, stress.get_view(), JF_invT);
    for (int cell=0; cell < workset.numCells; ++cell) {
      for (int node=0; node < numNodes; ++node) {
	for (int dim=0; dim<numDims; dim++)  Residual(cell,node,dim)=0.0;
	for (int qp=0; qp < numQPs; ++qp) {
	  for (int i=0; i<numDims; i++) {
	    for (int j=0; j<numDims; j++) {
              Residual(cell,node,i) += P(cell, qp, i, j) * wGradBF(cell, node, qp, j);
	    } 
	  } 
	} 
      } 
    }
  }
/** // Gravity term used for load stepping 
  for (int cell=0; cell < workset.numCells; ++cell) {
    for (int node=0; node < numNodes; ++node) {
      for (int qp=0; qp < numQPs; ++qp) {
         Residual(cell,node,2) +=  zGrav * wBF(cell, node, qp);
      } 
    } 
  }
**/
}
示例#2
0
void GPAMResid<EvalT, Traits>::
evaluateFields(typename Traits::EvalData workset)
{
  typedef Intrepid2::FunctionSpaceTools FST;

    //Set Redidual to 0, add Diffusion Term
    for (std::size_t cell=0; cell < workset.numCells; ++cell) {
      for (std::size_t node=0; node < numNodes; ++node) {
              for (std::size_t i=0; i<vecDim; i++)  Residual(cell,node,i)=0.0;
          for (std::size_t qp=0; qp < numQPs; ++qp) {
            for (std::size_t i=0; i<vecDim; i++) {
              for (std::size_t dim=0; dim<numDims; dim++) {
                Residual(cell,node,i) += Cgrad(cell, qp, i, dim) * wGradBF(cell, node, qp, dim);
    } } } } }

  // These both should always be true if transient is enabled
  if (workset.transientTerms && enableTransient) {
    for (std::size_t cell=0; cell < workset.numCells; ++cell) {
      for (std::size_t node=0; node < numNodes; ++node) {
          for (std::size_t qp=0; qp < numQPs; ++qp) {
            for (std::size_t i=0; i<vecDim; i++) {
                Residual(cell,node,i) += CDot(cell, qp, i) * wBF(cell, node, qp);
    } } } } }

  if (convectionTerm) {
    for (std::size_t cell=0; cell < workset.numCells; ++cell) {
      for (std::size_t node=0; node < numNodes; ++node) {
          for (std::size_t qp=0; qp < numQPs; ++qp) {
            for (std::size_t i=0; i<vecDim; i++) {
              for (std::size_t dim=0; dim<numDims; dim++) {
                Residual(cell,node,i) += u[dim]*Cgrad(cell, qp, i, dim) * wBF(cell, node, qp);
    } } } } } }

}
示例#3
0
void ElasticityResid<EvalT, Traits>::
evaluateFields(typename Traits::EvalData workset)
{
  typedef Intrepid::FunctionSpaceTools FST;

    for (std::size_t cell=0; cell < workset.numCells; ++cell) {
      for (std::size_t node=0; node < numNodes; ++node) {
              for (std::size_t dim=0; dim<numDims; dim++)  ExResidual(cell,node,dim)=0.0;
          for (std::size_t qp=0; qp < numQPs; ++qp) {
            for (std::size_t i=0; i<numDims; i++) {
              for (std::size_t dim=0; dim<numDims; dim++) {
                ExResidual(cell,node,i) += Stress(cell, qp, i, dim) * wGradBF(cell, node, qp, dim);
    } } } } }


  if (workset.transientTerms && enableTransient)
    for (std::size_t cell=0; cell < workset.numCells; ++cell) {
      for (std::size_t node=0; node < numNodes; ++node) {
          for (std::size_t qp=0; qp < numQPs; ++qp) {
            for (std::size_t i=0; i<numDims; i++) {
                ExResidual(cell,node,i) += uDotDot(cell, qp, i) * wBF(cell, node, qp);
    } } } }


//  FST::integrate<ScalarT>(ExResidual, Stress, wGradBF, Intrepid::COMP_CPP, false); // "false" overwrites

}
void XZHydrostatic_VelResid<EvalT, Traits>::
evaluateFields(typename Traits::EvalData workset)
{
#ifndef ALBANY_KOKKOS_UNDER_DEVELOPMENT
  for (int cell=0; cell < workset.numCells; ++cell) {
    for (int node=0; node < numNodes; ++node) {
      for (int level=0; level < numLevels; ++level) {
        for (int dim=0; dim < numDims; ++dim) {
          int qp = node; 
          Residual(cell,node,level,dim) = ( keGrad(cell,qp,level,dim) + PhiGrad(cell,qp,level,dim) )*wBF(cell,node,qp)
                                        + ( pGrad (cell,qp,level,dim)/density(cell,qp,level) )      *wBF(cell,node,qp)
                                        + etadotdVelx(cell,qp,level,dim)                            *wBF(cell,node,qp)
                                        + uDot(cell,qp,level,dim)                                   *wBF(cell,node,qp);

          for (int qp=0; qp < numQPs; ++qp) {
            Residual(cell,node,level,dim) += viscosity * DVelx(cell,qp,level,dim) * wGradBF(cell,node,qp,dim);
          }
        }
      }
    }
  }

#else
  Kokkos::parallel_for(XZHydrostatic_VelResid_Policy(0,workset.numCells),*this);

#endif
}
void MicroResidual<EvalT, Traits>::
evaluateFields(typename Traits::EvalData workset)
{
  typedef Intrepid2::FunctionSpaceTools FST;

    for (std::size_t cell=0; cell < workset.numCells; ++cell) {
      for (std::size_t node=0; node < numNodes; ++node) {
          for (std::size_t idim=0; idim<numDims; idim++)  
            for (std::size_t jdim=0; jdim<numDims; jdim++)  
              ExResidual(cell,node,idim,jdim)=0.0;
          for (std::size_t qp=0; qp < numQPs; ++qp) {
            for (std::size_t i=0; i<numDims; i++) {
              for (std::size_t j=0; j<numDims; j++) {
                for (std::size_t dim=0; dim<numDims; dim++) {
                  ExResidual(cell,node,i,j) += doubleStress(cell, qp, i, j, dim) * wGradBF(cell, node, qp, dim)
                                             + microStress(cell, qp, i, j) * wBF(cell, node, qp);
    } } } } } }


  if (workset.transientTerms && enableTransient)
    for (std::size_t cell=0; cell < workset.numCells; ++cell) {
      for (std::size_t node=0; node < numNodes; ++node) {
          for (std::size_t qp=0; qp < numQPs; ++qp) {
            for (std::size_t i=0; i<numDims; i++) {
              for (std::size_t j=0; j<numDims; j++) {
                ExResidual(cell,node,i,j) += epsDotDot(cell, qp, i, j) * wBF(cell, node, qp);
    } } } } }

}
void StokesContinuityResid<EvalT, Traits>::
evaluateFields(typename Traits::EvalData workset)
{
  typedef Intrepid::FunctionSpaceTools FST;

  for (std::size_t cell=0; cell < workset.numCells; ++cell) {
    for (std::size_t qp=0; qp < numQPs; ++qp) {
      divergence(cell,qp) = 0.0;
      for (std::size_t i=0; i < numDims; ++i) {
        divergence(cell,qp) += VGrad(cell,qp,i,i);
      }
    }
  }
  FST::integrate<ScalarT>(CResidual, divergence, wBF, Intrepid::COMP_CPP,  
                          false); // "false" overwrites

  contractDataFieldScalar<ScalarT>(CResidual, divergence, wBF,false); // "false" overwrites



  if (havePSPG) {
    for (std::size_t cell=0; cell < workset.numCells; ++cell) {
      for (std::size_t node=0; node < numNodes; ++node) {          
	for (std::size_t qp=0; qp < numQPs; ++qp) {               
	  for (std::size_t j=0; j < numDims; ++j) { 
	    CResidual(cell,node) += 
	      TauM(cell,qp)*Rm(cell,qp,j)*wGradBF(cell,node,qp,j);
	  }  
	}    
      }
    }
  }

}
void StokesL1L2Resid<EvalT, Traits>::
evaluateFields(typename Traits::EvalData workset)
{
  for (std::size_t cell=0; cell < workset.numCells; ++cell) {
    for (std::size_t node=0; node < numNodes; ++node) {
            for (std::size_t i=0; i<vecDim; i++)  Residual(cell,node,i)=0.0;
        for (std::size_t qp=0; qp < numQPs; ++qp) {
           Residual(cell,node,0) += 2.0*muLandIce(cell,qp)*((2.0*epsilonXX(cell,qp) + epsilonYY(cell,qp))*wGradBF(cell,node,qp,0) +
                                    epsilonXY(cell,qp)*wGradBF(cell,node,qp,1)) +
                                    force(cell,qp,0)*wBF(cell,node,qp);
           Residual(cell,node,1) += 2.0*muLandIce(cell,qp)*(epsilonXY(cell,qp)*wGradBF(cell,node,qp,0) +
                                      (epsilonXX(cell,qp) + 2.0*epsilonYY(cell,qp))*wGradBF(cell,node,qp,1))
                                  + force(cell,qp,1)*wBF(cell,node,qp);
              }
      }
    }
}
void VectorResidual<EvalT, Traits>::
evaluateFields(typename Traits::EvalData workset)
{
  for (std::size_t cell=0; cell < workset.numCells; ++cell) {
    for (std::size_t node=0; node < numNodes; ++node) {
        ExResidual(cell,node)=0.0;
        for (std::size_t qp=0; qp < numQPs; ++qp)
          for (std::size_t dim=0; dim<numDims; dim++)
            ExResidual(cell,node) += vector(cell, qp, dim) * wGradBF(cell, node, qp, dim);
    } 
  }
}
void ElasticityDispErrResid<EvalT, Traits>::
evaluateFields(typename Traits::EvalData workset)
{
  for (int cell=0; cell < workset.numCells; ++cell) {
    for (int node=0; node < numNodes; ++node) {
      for (int dim=0; dim<numDims; dim++)  ExResidual(cell,node,dim)=0.0;
      for (int qp=0; qp < numQPs; ++qp) {
        for (int i=0; i<numDims; i++) {
          ExResidual(cell,node,i) += DispResid(cell,node,i);
          for (int dim=0; dim<numDims; dim++) {
            ExResidual(cell,node,i) += ErrorStress(cell, qp, i, dim) * wGradBF(cell, node, qp, dim);
    } } } } }
}
void NSMomentumResid<EvalT, Traits>::
evaluateFields(typename Traits::EvalData workset)
{
  
  for (std::size_t cell=0; cell < workset.numCells; ++cell) {
    for (std::size_t node=0; node < numNodes; ++node) {          
      for (std::size_t i=0; i<numDims; i++) {
	MResidual(cell,node,i) = 0.0;
	for (std::size_t qp=0; qp < numQPs; ++qp) {
	  MResidual(cell,node,i) += 
	    (Rm(cell, qp, i)-pGrad(cell,qp,i))*wBF(cell,node,qp) -
	    P(cell,qp)*wGradBF(cell,node,qp,i);               
	  for (std::size_t j=0; j < numDims; ++j) { 
	    MResidual(cell,node,i) += 
	      mu(cell,qp)*(VGrad(cell,qp,i,j)+VGrad(cell,qp,j,i))*wGradBF(cell,node,qp,j);
//	      mu(cell,qp)*VGrad(cell,qp,i,j)*wGradBF(cell,node,qp,j);
	  }  
	}
      }
    }
  }
  
  if (haveSUPG) {
    for (std::size_t cell=0; cell < workset.numCells; ++cell) {
      for (std::size_t node=0; node < numNodes; ++node) {          
	for (std::size_t i=0; i<numDims; i++) {
	  for (std::size_t qp=0; qp < numQPs; ++qp) {           
	    for (std::size_t j=0; j < numDims; ++j) { 
	      MResidual(cell,node,i) += 
		rho(cell,qp)*TauM(cell,qp)*Rm(cell,qp,j)*V(cell,qp,j)*wGradBF(cell,node,qp,j);
	    }  
	  }
	}
      }
    }
  }
 
}
void StokesMomentumResid<EvalT, Traits>::
evaluateFields(typename Traits::EvalData workset)
{
  for (std::size_t cell=0; cell < workset.numCells; ++cell) {
    for (std::size_t node=0; node < numNodes; ++node) {          
      for (std::size_t i=0; i<numDims; i++) {
	MResidual(cell,node,i) = 0.0;
	for (std::size_t qp=0; qp < numQPs; ++qp) {
	  MResidual(cell,node,i) += 
	    force(cell,qp,i)*wBF(cell,node,qp) -
	     P(cell,qp)*wGradBF(cell,node,qp,i);          
	  for (std::size_t j=0; j < numDims; ++j) { 
	    MResidual(cell,node,i) += 
	      muFELIX(cell,qp)*(VGrad(cell,qp,i,j)+VGrad(cell,qp,j,i))*wGradBF(cell,node,qp,j);
//	      muFELIX(cell,qp)*VGrad(cell,qp,i,j)*wGradBF(cell,node,qp,j);
	  }  
	}
      }
    }
  }
  
 
}
void ReactDiffSystemResid<EvalT, Traits>::
evaluateFields(typename Traits::EvalData workset)
{
  typedef Intrepid2::FunctionSpaceTools<PHX::Device> FST;

  for (std::size_t cell=0; cell < workset.numCells; ++cell) {
    for (std::size_t node=0; node < numNodes; ++node) {
      for (std::size_t i=0; i<vecDim; i++)  Residual(cell,node,i) = 0.0;
      for (std::size_t qp=0; qp < numQPs; ++qp) {
        //- mu0*delta(u0) + a0*u0 + a1*u1 + a2*u2 = f0
        Residual(cell,node,0) += mu0*UGrad(cell,qp,0,0)*wGradBF(cell,node,qp,0) + 
                                 mu0*UGrad(cell,qp,0,1)*wGradBF(cell,node,qp,1) +
                                 mu0*UGrad(cell,qp,0,2)*wGradBF(cell,node,qp,2) -
                                 reactCoeff0[0]*U(cell,qp,0)*wBF(cell,node,qp) -
                                 reactCoeff0[1]*U(cell,qp,1)*wBF(cell,node,qp) -
                                 reactCoeff0[2]*U(cell,qp,2)*wBF(cell,node,qp) -
                                 forces[0]*wBF(cell,node,qp); 
        //- mu1*delta(u1) + b0*u0 + b1*u1 + b2*u2 = f1
        Residual(cell,node,1) += mu1*UGrad(cell,qp,1,0)*wGradBF(cell,node,qp,0) + 
                                 mu1*UGrad(cell,qp,1,1)*wGradBF(cell,node,qp,1) +
                                 mu1*UGrad(cell,qp,1,2)*wGradBF(cell,node,qp,2) -
                                 reactCoeff1[0]*U(cell,qp,0)*wBF(cell,node,qp) -
                                 reactCoeff1[1]*U(cell,qp,1)*wBF(cell,node,qp) -
                                 reactCoeff1[2]*U(cell,qp,2)*wBF(cell,node,qp) -
                                 forces[1]*wBF(cell,node,qp); 
        //- mu2*delta(u2) + c0*u0 + c1*u1 + c2*u2 = f2
        Residual(cell,node,2) += mu2*UGrad(cell,qp,2,0)*wGradBF(cell,node,qp,0) + 
                                 mu2*UGrad(cell,qp,2,1)*wGradBF(cell,node,qp,1) +
                                 mu2*UGrad(cell,qp,2,2)*wGradBF(cell,node,qp,2) -
                                 reactCoeff2[0]*U(cell,qp,0)*wBF(cell,node,qp) -
                                 reactCoeff2[1]*U(cell,qp,1)*wBF(cell,node,qp) -
                                 reactCoeff2[2]*U(cell,qp,2)*wBF(cell,node,qp) -
                                 forces[2]*wBF(cell,node,qp); 
      }
    }        
  }
}
KOKKOS_INLINE_FUNCTION
void XZHydrostatic_VelResid<EvalT, Traits>::
operator() (const XZHydrostatic_VelResid_Tag& tag, const int& cell) const{
  for (int node=0; node < numNodes; ++node) {
    for (int level=0; level < numLevels; ++level) {
      for (int dim=0; dim < numDims; ++dim) {
        int qp = node; 
        Residual(cell,node,level,dim) = ( keGrad(cell,qp,level,dim) + PhiGrad(cell,qp,level,dim) )*wBF(cell,node,qp)
                                      + ( pGrad (cell,qp,level,dim)/density(cell,qp,level) )      *wBF(cell,node,qp)
                                      + etadotdVelx(cell,qp,level,dim)                            *wBF(cell,node,qp)
                                      + uDot(cell,qp,level,dim)                                   *wBF(cell,node,qp);

        for (int qp=0; qp < numQPs; ++qp) {
          Residual(cell,node,level,dim) += viscosity * DVelx(cell,qp,level,dim) * wGradBF(cell,node,qp,dim);
        }
      }
    }
  }
}
void ThermoPoroPlasticityResidMomentum<EvalT, Traits>::
evaluateFields(typename Traits::EvalData workset)
{
  typedef Intrepid::FunctionSpaceTools FST;
  typedef Intrepid::RealSpaceTools<ScalarT> RST;

    RST::inverse(F_inv, defgrad);
    RST::transpose(F_invT, F_inv);
    FST::scalarMultiplyDataData<ScalarT>(JF_invT, J, F_invT);
    FST::scalarMultiplyDataData<ScalarT>(thermoEPS, alphaSkeleton , JF_invT);

    for (int cell=0; cell < workset.numCells; ++cell) {
      for (int node=0; node < numNodes; ++node) {
              for (int dim=0; dim<numDims; dim++)  {
            	  ExResidual(cell,node,dim)=0.0;
              }
          for (int qp=0; qp < numQPs; ++qp) {

        	dTemp = Temp(cell,qp) - TempRef(cell,qp);

            for (int i=0; i<numDims; i++) {
              for (int dim=0; dim<numDims; dim++) {
                ExResidual(cell,node,i) += (TotalStress(cell, qp, i, dim)
                		                   - Bulk(cell,qp)*thermoEPS(cell, qp, i, dim)
                		                   *dTemp)
                		                   * wGradBF(cell, node, qp, dim);
    } } } } }

//Irina comment: everything below was commented out
 /*
  if (workset.transientTerms && enableTransient)
    for (int cell=0; cell < workset.numCells; ++cell) {
      for (int node=0; node < numNodes; ++node) {
          for (int qp=0; qp < numQPs; ++qp) {
            for (int i=0; i<numDims; i++) {
                ExResidual(cell,node,i) += uDotDot(cell, qp, i) * wBF(cell, node, qp);
    } } } }
*/

//   FST::integrate<ScalarT>(ExResidual, TotalStress, wGradBF, Intrepid::COMP_CPP, false); // "false" overwrites

}
void NSThermalEqResid<EvalT, Traits>::
evaluateFields(typename Traits::EvalData workset)
{
  typedef Intrepid2::FunctionSpaceTools FST;

  FST::scalarMultiplyDataData<ScalarT> (flux, ThermalCond, TGrad);

  FST::integrate<ScalarT>(TResidual, flux, wGradBF, Intrepid2::COMP_CPP, false); // "false" overwrites
  
  for (std::size_t cell=0; cell < workset.numCells; ++cell) {
    for (std::size_t qp=0; qp < numQPs; ++qp) {
      convection(cell,qp) = 0.0;
      if (haveSource) convection(cell,qp) -= Source(cell,qp);
      if (workset.transientTerms && enableTransient) 
	convection(cell,qp) += rho(cell,qp) * Cp(cell,qp) * Tdot(cell,qp);
      if (haveFlow) {
	for (std::size_t i=0; i < numDims; ++i) { 
	  convection(cell,qp) += 
	    rho(cell,qp) * Cp(cell,qp) * V(cell,qp,i) * TGrad(cell,qp,i);
	}
      }
    }
  }

  FST::integrate<ScalarT>(TResidual, convection, wBF, Intrepid2::COMP_CPP, true); // "true" sums into

  if (haveSUPG) {
    for (std::size_t cell=0; cell < workset.numCells; ++cell) {
      for (std::size_t node=0; node < numNodes; ++node) {          
	for (std::size_t qp=0; qp < numQPs; ++qp) {               
	  for (std::size_t j=0; j < numDims; ++j) { 
	    TResidual(cell,node) += 
	      rho(cell,qp) * Cp(cell,qp) * TauT(cell,qp) * convection(cell,qp) *
	      V(cell,qp,j) * wGradBF(cell,node,qp,j);
	  }  
	}
      }
    }
  }

}
void
TLPoroPlasticityResidMomentum<EvalT, Traits>::evaluateFields(
    typename Traits::EvalData workset)
{
  typedef Intrepid2::FunctionSpaceTools<PHX::Device> FST;
  typedef Intrepid2::RealSpaceTools<PHX::Device>     RST;
  RST::inverse(F_inv, defgrad.get_view());
  RST::transpose(F_invT, F_inv);
  FST::scalarMultiplyDataData(JF_invT, J.get_view(), F_invT);
  // FST::tensorMultiplyDataData(P.get_view(), TotalStress.get_view(), JF_invT);

  for (int cell = 0; cell < workset.numCells; ++cell) {
    for (int node = 0; node < numNodes; ++node) {
      for (int dim = 0; dim < numDims; dim++) ExResidual(cell, node, dim) = 0.0;
      for (int qp = 0; qp < numQPs; ++qp) {
        for (int i = 0; i < numDims; i++) {
          for (int dim = 0; dim < numDims; dim++) {
            ExResidual(cell, node, i) +=
                TotalStress(cell, qp, i, dim) * wGradBF(cell, node, qp, dim);
          }
        }
      }
    }
  }

  if (workset.transientTerms && enableTransient)
    for (int cell = 0; cell < workset.numCells; ++cell) {
      for (int node = 0; node < numNodes; ++node) {
        for (int qp = 0; qp < numQPs; ++qp) {
          for (int i = 0; i < numDims; i++) {
            ExResidual(cell, node, i) +=
                uDotDot(cell, qp, i) * wBF(cell, node, qp);
          }
        }
      }
    }

  //   FST::integrate(ExResidual.get_view(), TotalStress.get_view(),
  //   wGradBF.get_view(), false); // "false" overwrites
}
示例#17
0
void StokesFOResid<EvalT, Traits>::
evaluateFields(typename Traits::EvalData workset)
{
  typedef Intrepid::FunctionSpaceTools FST; 

  for (std::size_t i=0; i < Residual.size(); ++i) Residual(i)=0.0;

  if (numDims == 3) { //3D case
    if (eqn_type == FELIX) {
    for (std::size_t cell=0; cell < workset.numCells; ++cell) {
      for (std::size_t qp=0; qp < numQPs; ++qp) {
        ScalarT& mu = muFELIX(cell,qp);
        ScalarT strs00 = 2.0*mu*(2.0*Ugrad(cell,qp,0,0) + Ugrad(cell,qp,1,1));
        ScalarT strs11 = 2.0*mu*(2.0*Ugrad(cell,qp,1,1) + Ugrad(cell,qp,0,0));
        ScalarT strs01 = mu*(Ugrad(cell,qp,1,0)+ Ugrad(cell,qp,0,1));
        ScalarT strs02 = mu*Ugrad(cell,qp,0,2);
        ScalarT strs12 = mu*Ugrad(cell,qp,1,2);
        for (std::size_t node=0; node < numNodes; ++node) {
             Residual(cell,node,0) += strs00*wGradBF(cell,node,qp,0) + 
                                      strs01*wGradBF(cell,node,qp,1) + 
                                      strs02*wGradBF(cell,node,qp,2);
             Residual(cell,node,1) += strs01*wGradBF(cell,node,qp,0) +
                                      strs11*wGradBF(cell,node,qp,1) + 
                                      strs12*wGradBF(cell,node,qp,2); 
        }
      }
      for (std::size_t qp=0; qp < numQPs; ++qp) {
        ScalarT& frc0 = force(cell,qp,0);
        ScalarT& frc1 = force(cell,qp,1);
        for (std::size_t node=0; node < numNodes; ++node) {
             Residual(cell,node,0) += frc0*wBF(cell,node,qp);
             Residual(cell,node,1) += frc1*wBF(cell,node,qp); 
        }
      }
    } }
    else if (eqn_type == POISSON) { //Laplace (Poisson) operator
    for (std::size_t cell=0; cell < workset.numCells; ++cell) {
      for (std::size_t node=0; node < numNodes; ++node) {
          for (std::size_t qp=0; qp < numQPs; ++qp) {
             Residual(cell,node,0) += Ugrad(cell,qp,0,0)*wGradBF(cell,node,qp,0) + 
                                      Ugrad(cell,qp,0,1)*wGradBF(cell,node,qp,1) + 
                                      Ugrad(cell,qp,0,2)*wGradBF(cell,node,qp,2) +  
                                      force(cell,qp,0)*wBF(cell,node,qp);
              }
           
    } } }
   }
   else { //2D case
   if (eqn_type == FELIX) { 
    for (std::size_t cell=0; cell < workset.numCells; ++cell) {
      for (std::size_t node=0; node < numNodes; ++node) {
          for (std::size_t qp=0; qp < numQPs; ++qp) {
             Residual(cell,node,0) += 2.0*muFELIX(cell,qp)*((2.0*Ugrad(cell,qp,0,0) + Ugrad(cell,qp,1,1))*wGradBF(cell,node,qp,0) + 
                                      0.5*(Ugrad(cell,qp,0,1) + Ugrad(cell,qp,1,0))*wGradBF(cell,node,qp,1)) + 
                                      force(cell,qp,0)*wBF(cell,node,qp);
             Residual(cell,node,1) += 2.0*muFELIX(cell,qp)*(0.5*(Ugrad(cell,qp,0,1) + Ugrad(cell,qp,1,0))*wGradBF(cell,node,qp,0) +
                                      (Ugrad(cell,qp,0,0) + 2.0*Ugrad(cell,qp,1,1))*wGradBF(cell,node,qp,1)) + force(cell,qp,1)*wBF(cell,node,qp); 
              }
           
    } } }
    else if (eqn_type == POISSON) { //Laplace (Poisson) operator
    for (std::size_t cell=0; cell < workset.numCells; ++cell) {
      for (std::size_t node=0; node < numNodes; ++node) {
          for (std::size_t qp=0; qp < numQPs; ++qp) {
             Residual(cell,node,0) += Ugrad(cell,qp,0,0)*wGradBF(cell,node,qp,0) + 
                                      Ugrad(cell,qp,0,1)*wGradBF(cell,node,qp,1) + 
                                      force(cell,qp,0)*wBF(cell,node,qp);
              }
           
    } } }
   }
}
void ComputeHierarchicBasis<EvalT, Traits>::
evaluateFields(typename Traits::EvalData workset)
{

  // do some work to get the pumi discretization and the apf mesh
  // this is so we can use the pumi mesh database to compute
  // mesh / basis function quantities.
  Teuchos::RCP<Albany::AbstractDiscretization> discretization =
    app->getDiscretization();

  Teuchos::RCP<Albany::PUMIDiscretization> pumiDiscretization =
    Teuchos::rcp_dynamic_cast<Albany::PUMIDiscretization>(discretization);

  Teuchos::RCP<Albany::PUMIMeshStruct> pumiMeshStruct =
    pumiDiscretization->getPUMIMeshStruct();

  // get the element block index
  // this will allow us to index into buckets
  ebIndex = pumiMeshStruct->ebNameToIndex[workset.EBName];

  // get the buckets
  // this is the elements of the apf mesh indexed by
  // buckets[Elem Block Index][Cell Index]
  buckets = pumiDiscretization->getBuckets();
  
  // get the apf mesh
  // this is used for a variety of apf things
  mesh = pumiMeshStruct->getMesh();

  // get the apf heirarchic shape
  // this is used to get shape function values / gradients
  shape = apf::getHierarchic(polynomialOrder);

  for (int cell=0; cell < workset.numCells; ++cell)
  {

    // get the apf objects associated with this cell
    apf::MeshEntity* element = buckets[ebIndex][cell];
    apf::MeshElement* meshElement = apf::createMeshElement(mesh, element);

    for (int qp=0; qp < numQPs; ++qp)
    {
      
      // get the parametric value of the current integration point
      apf::getIntPoint(meshElement, cubatureDegree, qp, point);

      // set the jacobian determinant
      detJ(cell, qp) = apf::getDV(meshElement, point);
      assert( detJ(cell, qp) > 0.0 );

      // get the integration point weight associated with this qp
      double w = apf::getIntWeight(meshElement, cubatureDegree, qp);

      // weight the determinant of the jacobian by the qp weight
      weightedDV(cell, qp) = w * detJ(cell,qp);

      // get the shape function values and gradients at this point
      apf::getBF(shape, meshElement, point, bf);
      apf::getGradBF(shape, meshElement, point, gbf);

      for (int node=0; node < numNodes; ++node)
      {
        BF(cell, node, qp) = bf[node];
        wBF(cell, node, qp) = weightedDV(cell, qp) * bf[node];
        for (int dim=0; dim < numDims; ++dim)
        {
          GradBF(cell, node, qp, dim) = gbf[node][dim];
          wGradBF(cell, node, qp, dim) = weightedDV(cell,qp) * gbf[node][dim];
        }
      }

    }

    // do some memory cleanup to keep everyone happy
    apf::destroyMeshElement(meshElement);

  }

}