void panzer::GatherTangents<EvalT, Traits>:: evaluateFields(typename Traits::EvalData workset) { if(workset.num_cells<=0) return; else { const shards::CellTopology & parentCell = *basis->getCellTopology(); int cellDim = parentCell.getDimension(); int numEdges = gatherFieldTangents.dimension(1); refEdgeTan = Intrepid2::FieldContainer<ScalarT>(numEdges,cellDim); for(int i=0;i<numEdges;i++) { Intrepid2::FieldContainer<double> refEdgeTan_local(cellDim); Intrepid2::CellTools<double>::getReferenceEdgeTangent(refEdgeTan_local, i, parentCell); for(int d=0;d<cellDim;d++) refEdgeTan(i,d) = refEdgeTan_local(d); } // Loop over workset faces and edge points for(std::size_t c=0;c<workset.num_cells;c++) { for(int pt = 0; pt < numEdges; pt++) { // Apply parent cell Jacobian to ref. edge tangent for(int i = 0; i < cellDim; i++) { edgeTan(c, pt, i) = 0.0; for(int j = 0; j < cellDim; j++){ edgeTan(c, pt, i) += pointValues.jac(c, pt, i, j)*refEdgeTan(pt,j); }// for j }// for i }// for pt }// for pCell // Multiply tangent by orientation for(std::size_t c=0;c<workset.num_cells;c++) { for(int b=0;b<gatherFieldTangents.dimension(1);b++) { for(int d=0;d<gatherFieldTangents.dimension(2);d++) { gatherFieldTangents(c,b,d) = edgeTan(c,b,d)*dof_orientation(c,b); } } } } }
//********************************************************************** PHX_EVALUATE_FIELDS(DirichletResidual_EdgeBasis,workset) { if(workset.num_cells<=0) return; residual.deep_copy(ScalarT(0.0)); if(workset.subcell_dim==1) { Intrepid2::CellTools<ScalarT>::getPhysicalEdgeTangents(edgeTan, pointValues.jac, this->wda(workset).subcell_index, *basis->getCellTopology()); for(std::size_t c=0;c<workset.num_cells;c++) { for(int b=0;b<dof.dimension(1);b++) { for(int d=0;d<dof.dimension(2);d++) residual(c,b) += (dof(c,b,d)-value(c,b,d))*edgeTan(c,b,d); } } } else if(workset.subcell_dim==2) { // we need to compute the tangents on each edge for each cell. // how do we do this???? const shards::CellTopology & parentCell = *basis->getCellTopology(); int cellDim = parentCell.getDimension(); int numEdges = dof.dimension(1); refEdgeTan = Kokkos::createDynRankView(residual.get_kokkos_view(),"refEdgeTan",numEdges,cellDim); for(int i=0;i<numEdges;i++) { Kokkos::DynRankView<double,PHX::Device> refEdgeTan_local("refEdgeTan_local",cellDim); Intrepid2::CellTools<double>::getReferenceEdgeTangent(refEdgeTan_local, i, parentCell); for(int d=0;d<cellDim;d++) refEdgeTan(i,d) = refEdgeTan_local(d); } // Loop over workset faces and edge points for(std::size_t c=0;c<workset.num_cells;c++) { for(int pt = 0; pt < numEdges; pt++) { // Apply parent cell Jacobian to ref. edge tangent for(int i = 0; i < cellDim; i++) { edgeTan(c, pt, i) = 0.0; for(int j = 0; j < cellDim; j++){ edgeTan(c, pt, i) += pointValues.jac(c, pt, i, j)*refEdgeTan(pt,j); }// for j }// for i }// for pt }// for pCell for(std::size_t c=0;c<workset.num_cells;c++) { for(int b=0;b<dof.dimension(1);b++) { for(int d=0;d<dof.dimension(2);d++) residual(c,b) += (dof(c,b,d)-value(c,b,d))*edgeTan(c,b,d); } } } else { // don't know what to do TEUCHOS_ASSERT(false); } // loop over residuals scaling by orientation. This gurantees // everything is oriented in the "positive" direction, this allows // sums acrossed processor to be oriented in the same way (right?) for(std::size_t c=0;c<workset.num_cells;c++) { for(int b=0;b<dof.dimension(1);b++) { residual(c,b) *= dof_orientation(c,b); } } }