43 #ifndef PANZER_PROJECT_TO_EDGES_IMPL_HPP
44 #define PANZER_PROJECT_TO_EDGES_IMPL_HPP
46 #include "Teuchos_Assert.hpp"
47 #include "Phalanx_DataLayout.hpp"
49 #include "Intrepid2_Cubature.hpp"
50 #include "Intrepid2_DefaultCubatureFactory.hpp"
51 #include "Intrepid2_FunctionSpaceTools.hpp"
52 #include "Intrepid2_OrientationTools.hpp"
56 #include "Kokkos_ViewFactory.hpp"
58 #include "Teuchos_FancyOStream.hpp"
60 template<
typename EvalT,
typename Traits>
65 dof_name = (p.
get< std::string >(
"DOF Name"));
73 if(p.
isType<
int>(
"Quadrature Order"))
74 quad_degree = p.
get<
int>(
"Quadrature Order");
82 result = PHX::MDField<ScalarT,Cell,BASIS>(dof_name,basis_layout);
83 this->addEvaluatedField(result);
85 tangents = PHX::MDField<const ScalarT,Cell,BASIS,Dim>(dof_name+
"_Tangents",vector_layout);
86 this->addDependentField(tangents);
89 const shards::CellTopology & parentCell = *basis->getCellTopology();
90 Intrepid2::DefaultCubatureFactory quadFactory;
92 = quadFactory.create<PHX::exec_space,double,
double>(parentCell.getCellTopologyData(1,0), quad_degree);
93 int numQPoints = quadRule->getNumPoints();
95 vector_values.resize(numQPoints);
96 for (
int qp(0); qp < numQPoints; ++qp)
98 vector_values[qp] = PHX::MDField<const ScalarT,Cell,BASIS,Dim>(dof_name+
"_Vector"+
"_qp_"+std::to_string(qp),vector_layout);
99 this->addDependentField(vector_values[qp]);
103 std::string orientationFieldName = basis->name() +
" Orientation";
104 dof_orientation = PHX::MDField<const ScalarT,Cell,NODE>(orientationFieldName,basis_layout);
105 this->addDependentField(dof_orientation);
107 gatherFieldTangents = PHX::MDField<ScalarT,Cell,NODE,Dim>(dof_name+
"_Tangents",basis->functional_grad);
108 this->addEvaluatedField(gatherFieldTangents);
111 vector_values.resize(1);
112 vector_values[0] = PHX::MDField<const ScalarT,Cell,BASIS,Dim>(dof_name+
"_Vector",vector_layout);
113 this->addDependentField(vector_values[0]);
116 this->setName(
"Project To Edges");
120 template<
typename EvalT,
typename Traits>
127 num_pts = vector_values[0].extent(1);
128 num_dim = vector_values[0].extent(2);
135 template<
typename EvalT,
typename Traits>
139 const shards::CellTopology & parentCell = *basis->getCellTopology();
140 const int intDegree = basis->order();
142 Intrepid2::DefaultCubatureFactory quadFactory;
146 if (quad_degree == 0){
162 Kokkos::DynRankView<double,PHX::Device> v0(
"v0", num_dim), v1(
"v1", num_dim);
163 const unsigned num_edges = parentCell.getEdgeCount();
164 std::vector<double> refEdgeWt(num_edges, 0.0);
165 for (
unsigned e=0; e<num_edges; e++) {
166 const auto v0_id = parentCell.getNodeMap(1, e, 0);
167 const auto v1_id = parentCell.getNodeMap(1, e, 1);
168 Intrepid2::CellTools<PHX::exec_space>::getReferenceVertex(v0, parentCell, v0_id);
169 Intrepid2::CellTools<PHX::exec_space>::getReferenceVertex(v1, parentCell, v1_id);
172 for (
int d=0;d<num_dim;++d)
173 norm += (v0(d) - v1(d))*(v0(d) - v1(d));
175 refEdgeWt[e] = sqrt(norm);
179 for (index_t cell = 0; cell < workset.
num_cells; ++cell) {
180 for (
int p = 0; p < num_pts; ++p) {
182 for (
int dim = 0; dim < num_dim; ++dim)
183 result(cell,p) += vector_values[0](cell,p,dim) * tangents(cell,p,dim);
184 result(cell,p) *= refEdgeWt[p];
196 int numEdges = gatherFieldTangents.extent(1);
197 Kokkos::DynRankView<ScalarT,typename PHX::DevLayout<ScalarT>::type,PHX::Device> refEdgeTan =
Kokkos::createDynRankView(gatherFieldTangents.get_static_view(),
"refEdgeTan",numEdges,num_dim);
198 for(
int i=0;i<numEdges;i++) {
199 Kokkos::DynRankView<double,typename PHX::DevLayout<ScalarT>::type,PHX::Device> refEdgeTan_local(
"refEdgeTan_local",num_dim);
200 Intrepid2::CellTools<PHX::exec_space>::getReferenceEdgeTangent(refEdgeTan_local, i, parentCell);
202 for(
int d=0;d<num_dim;d++)
203 refEdgeTan(i,d) = refEdgeTan_local(d);
207 for (index_t cell = 0; cell < workset.
num_cells; ++cell) {
210 Kokkos::DynRankView<double,PHX::Device> physicalNodes(
"physicalNodes",1,vertex_coords.extent(1),num_dim);
211 for (
int point(0); point < vertex_coords.extent_int(1); ++point)
213 for (
int ict(0); ict < num_dim; ict++)
214 physicalNodes(0, point, ict) = vertex_coords(cell, point, ict);
218 for (
int p = 0; p < num_pts; ++p){
222 const shards::CellTopology & subcell = parentCell.getCellTopologyData(subcell_dim,p);
223 edgeQuad = quadFactory.create<PHX::exec_space,double,
double>(subcell, quad_degree);
225 edgeQuad->getNumPoints() ==
static_cast<int>(vector_values.size()));
226 Kokkos::DynRankView<double,PHX::Device> quadWts(
"quadWts",edgeQuad->getNumPoints());
227 Kokkos::DynRankView<double,PHX::Device> quadPts(
"quadPts",edgeQuad->getNumPoints(),subcell_dim);
228 edgeQuad->getCubature(quadPts,quadWts);
231 Kokkos::DynRankView<double,PHX::Device> refQuadPts(
"refQuadPts",edgeQuad->getNumPoints(),num_dim);
232 Intrepid2::CellTools<PHX::exec_space>::mapToReferenceSubcell(refQuadPts, quadPts, subcell_dim, p, parentCell);
236 Kokkos::DynRankView<double,PHX::Device> jacobianSide(
"jacobianSide", 1, edgeQuad->getNumPoints(), num_dim, num_dim);
237 Intrepid2::CellTools<PHX::exec_space>::setJacobian(jacobianSide, refQuadPts, physicalNodes, parentCell);
240 Kokkos::DynRankView<double,PHX::Device> weighted_measure(
"weighted_measure",1,edgeQuad->getNumPoints());
241 Kokkos::DynRankView<double,PHX::Device> scratch_space(
"scratch_space",jacobianSide.span());
242 Intrepid2::FunctionSpaceTools<PHX::exec_space>::computeEdgeMeasure(weighted_measure, jacobianSide, quadWts, p, parentCell,scratch_space);
245 for (
int qp = 0; qp < edgeQuad->getNumPoints(); ++qp) {
248 std::vector<ScalarT> edgeTan(num_dim);
249 for(
int i = 0; i < 3; i++) {
250 edgeTan[i] = (Sacado::ScalarValue<ScalarT>::eval(jacobianSide(0,qp,i,0)*refEdgeTan(p,0))
251 + Sacado::ScalarValue<ScalarT>::eval(jacobianSide(0,qp,i,1)*refEdgeTan(p,1))
252 + Sacado::ScalarValue<ScalarT>::eval(jacobianSide(0,qp,i,2)*refEdgeTan(p,2)))
253 * dof_orientation(cell,p);
258 for(
int dim = 0; dim < num_dim; ++dim){
259 tnorm += edgeTan[dim]*edgeTan[dim];
261 tnorm = std::sqrt(tnorm);
265 for (
int dim = 0; dim < num_dim; ++dim)
266 result(cell,p) += weighted_measure(0,qp) * vector_values[qp](cell,p,dim) * edgeTan[dim] / tnorm;
Kokkos::DynRankView< typename InputArray::value_type, PHX::Device > createDynRankView(const InputArray &a, const std::string &name, const DimensionPack...dims)
Wrapper to simplify Panzer use of Sacado ViewFactory.
Teuchos::RCP< const std::vector< Intrepid2::Orientation > > orientations_
T & get(const std::string &name, T def_value)
void postRegistrationSetup(typename Traits::SetupData d, PHX::FieldManager< Traits > &vm)
CellCoordArray cell_vertex_coordinates
PHX::MDField< ScalarT, panzer::Cell, panzer::IP > result
A field that will be used to build up the result of the integral we're performing.
void evaluateFields(typename Traits::EvalData d)
bool isType(const std::string &name) const
#define TEUCHOS_ASSERT(assertion_test)