11#ifndef PANZER_DOF_CURL_IMPL_HPP
12#define PANZER_DOF_CURL_IMPL_HPP
17#include "Intrepid2_FunctionSpaceTools.hpp"
18#include "Phalanx_KokkosDeviceTypes.hpp"
25template <
typename ScalarT,
typename Array,
int spaceDim>
26class EvaluateCurlWithSens_Vector {
27 PHX::MDField<const ScalarT,Cell,Point> dof_value;
28 PHX::MDField<ScalarT,Cell,Point,Dim> dof_curl;
35 typedef typename PHX::ExecutionSpace execution_space;
37 EvaluateCurlWithSens_Vector(PHX::MDField<const ScalarT,Cell,Point> in_dof_value,
38 PHX::MDField<ScalarT,Cell,Point,Dim> in_dof_curl,
40 : dof_value(in_dof_value), dof_curl(in_dof_curl), curl_basis(in_curl_basis)
42 numFields = curl_basis.extent(1);
43 numPoints = curl_basis.extent(2);
45 KOKKOS_INLINE_FUNCTION
46 void operator()(
const unsigned int cell)
const
48 for (
int pt=0; pt<numPoints; pt++) {
49 for (
int d=0; d<spaceDim; d++) {
52 dof_curl(cell,pt,d) = dof_value(cell, 0) * curl_basis(cell, 0, pt, d);
53 for (
int bf=1; bf<numFields; bf++)
54 dof_curl(cell,pt,d) += dof_value(cell, bf) * curl_basis(cell, bf, pt, d);
60template <
typename ScalarT,
typename ArrayT>
61void evaluateCurl_withSens_vector(
int numCells,
62 PHX::MDField<ScalarT,Cell,Point,Dim> & dof_curl,
63 PHX::MDField<const ScalarT,Cell,Point> & dof_value,
64 const ArrayT & curl_basis)
68 int numFields = curl_basis.extent(1);
69 int numPoints = curl_basis.extent(2);
70 int spaceDim = curl_basis.extent(3);
72 for (
int cell=0; cell<numCells; cell++) {
73 for (
int pt=0; pt<numPoints; pt++) {
74 for (
int d=0; d<spaceDim; d++) {
77 dof_curl(cell,pt,d) = dof_value(cell, 0) * curl_basis(cell, 0, pt, d);
78 for (
int bf=1; bf<numFields; bf++)
79 dof_curl(cell,pt,d) += dof_value(cell, bf) * curl_basis(cell, bf, pt, d);
87template <
typename ScalarT,
typename Array>
88class EvaluateCurlWithSens_Scalar {
89 PHX::MDField<const ScalarT,Cell,Point> dof_value;
90 PHX::MDField<ScalarT,Cell,Point> dof_curl;
97 typedef typename PHX::ExecutionSpace execution_space;
99 EvaluateCurlWithSens_Scalar(PHX::MDField<const ScalarT,Cell,Point> in_dof_value,
100 PHX::MDField<ScalarT,Cell,Point> in_dof_curl,
102 : dof_value(in_dof_value), dof_curl(in_dof_curl), curl_basis(in_curl_basis)
104 numFields = curl_basis.extent(1);
105 numPoints = curl_basis.extent(2);
107 KOKKOS_INLINE_FUNCTION
108 void operator()(
const unsigned int cell)
const
110 for (
int pt=0; pt<numPoints; pt++) {
113 dof_curl(cell,pt) = dof_value(cell, 0) * curl_basis(cell, 0, pt);
114 for (
int bf=1; bf<numFields; bf++)
115 dof_curl(cell,pt) += dof_value(cell, bf) * curl_basis(cell, bf, pt);
120template <
typename ScalarT,
typename ArrayT>
121void evaluateCurl_withSens_scalar(
int numCells,
122 PHX::MDField<ScalarT,Cell,Point> & dof_curl,
123 PHX::MDField<const ScalarT,Cell,Point> & dof_value,
124 const ArrayT & curl_basis)
128 int numFields = curl_basis.extent(1);
129 int numPoints = curl_basis.extent(2);
131 for (
int cell=0; cell<numCells; cell++) {
132 for (
int pt=0; pt<numPoints; pt++) {
135 dof_curl(cell,pt) = dof_value(cell, 0) * curl_basis(cell, 0, pt);
136 for (
int bf=1; bf<numFields; bf++)
137 dof_curl(cell,pt) += dof_value(cell, bf) * curl_basis(cell, bf, pt);
144template <
typename ScalarT,
typename Array,
int spaceDim>
145class EvaluateCurlFastSens_Vector {
146 PHX::MDField<const ScalarT,Cell,Point> dof_value;
147 PHX::MDField<ScalarT,Cell,Point,Dim> dof_curl;
148 PHX::View<const int*> offsets;
155 typedef typename PHX::ExecutionSpace execution_space;
157 EvaluateCurlFastSens_Vector(PHX::MDField<const ScalarT,Cell,Point> in_dof_value,
158 PHX::MDField<ScalarT,Cell,Point,Dim> in_dof_curl,
159 PHX::View<const int*> in_offsets,
161 : dof_value(in_dof_value), dof_curl(in_dof_curl), offsets(in_offsets), curl_basis(in_curl_basis)
163 numFields = curl_basis.extent(1);
164 numPoints = curl_basis.extent(2);
166 KOKKOS_INLINE_FUNCTION
167 void operator()(
const unsigned int cell)
const
169 for (
int pt=0; pt<numPoints; pt++) {
170 for (
int d=0; d<spaceDim; d++) {
173 dof_curl(cell,pt,d) = dof_value(cell, 0).val() * curl_basis(cell, 0, pt, d);
174 dof_curl(cell,pt,d).fastAccessDx(offsets(0)) = dof_value(cell, 0).fastAccessDx(offsets(0)) * curl_basis(cell, 0, pt, d);
175 for (
int bf=1; bf<numFields; bf++) {
176 dof_curl(cell,pt,d).val() += dof_value(cell, bf).val() * curl_basis(cell, bf, pt, d);
177 dof_curl(cell,pt,d).fastAccessDx(offsets(bf)) += dof_value(cell, bf).fastAccessDx(offsets(bf)) * curl_basis(cell, bf, pt, d);
183template <
typename ScalarT,
typename ArrayT>
184void evaluateCurl_fastSens_vector(
int numCells,
185 PHX::MDField<ScalarT,Cell,Point,Dim> & dof_curl,
186 PHX::MDField<const ScalarT,Cell,Point> & dof_value,
187 const std::vector<int> & offsets,
188 const ArrayT & curl_basis)
191 int numFields = curl_basis.extent(1);
192 int numPoints = curl_basis.extent(2);
193 int spaceDim = curl_basis.extent(3);
195 for (
int cell=0; cell<numCells; cell++) {
196 for (
int pt=0; pt<numPoints; pt++) {
197 for (
int d=0; d<spaceDim; d++) {
200 dof_curl(cell,pt,d) = ScalarT(numFields, dof_value(cell, 0).val() * curl_basis(cell, 0, pt, d));
201 dof_curl(cell,pt,d).fastAccessDx(offsets[0]) = dof_value(cell, 0).fastAccessDx(offsets[0]) * curl_basis(cell, 0, pt, d);
202 for (
int bf=1; bf<numFields; bf++) {
203 dof_curl(cell,pt,d).val() += dof_value(cell, bf).val() * curl_basis(cell, bf, pt, d);
204 dof_curl(cell,pt,d).fastAccessDx(offsets[bf]) += dof_value(cell, bf).fastAccessDx(offsets[bf]) * curl_basis(cell, bf, pt, d);
213template <
typename ScalarT,
typename Array>
214class EvaluateCurlFastSens_Scalar {
215 PHX::MDField<const ScalarT,Cell,Point> dof_value;
216 PHX::MDField<ScalarT,Cell,Point> dof_curl;
217 PHX::View<const int*> offsets;
224 typedef typename PHX::ExecutionSpace execution_space;
226 EvaluateCurlFastSens_Scalar(PHX::MDField<const ScalarT,Cell,Point> in_dof_value,
227 PHX::MDField<ScalarT,Cell,Point> in_dof_curl,
228 PHX::View<const int*> in_offsets,
230 : dof_value(in_dof_value), dof_curl(in_dof_curl), offsets(in_offsets), curl_basis(in_curl_basis)
232 numFields = curl_basis.extent(1);
233 numPoints = curl_basis.extent(2);
235 KOKKOS_INLINE_FUNCTION
236 void operator()(
const unsigned int cell)
const
238 for (
int pt=0; pt<numPoints; pt++) {
241 dof_curl(cell,pt) = dof_value(cell, 0).val() * curl_basis(cell, 0, pt);
242 dof_curl(cell,pt).fastAccessDx(offsets(0)) = dof_value(cell, 0).fastAccessDx(offsets(0)) * curl_basis(cell, 0, pt);
243 for (
int bf=1; bf<numFields; bf++) {
244 dof_curl(cell,pt).val() += dof_value(cell, bf).val() * curl_basis(cell, bf, pt);
245 dof_curl(cell,pt).fastAccessDx(offsets(bf)) += dof_value(cell, bf).fastAccessDx(offsets(bf)) * curl_basis(cell, bf, pt);
250template <
typename ScalarT,
typename ArrayT>
251void evaluateCurl_fastSens_scalar(
int numCells,
252 PHX::MDField<ScalarT,Cell,Point> & dof_curl,
253 PHX::MDField<const ScalarT,Cell,Point> & dof_value,
254 const std::vector<int> & offsets,
255 const ArrayT & curl_basis)
258 int numFields = curl_basis.extent(1);
259 int numPoints = curl_basis.extent(2);
261 for (
int cell=0; cell<numCells; cell++) {
262 for (
int pt=0; pt<numPoints; pt++) {
265 dof_curl(cell,pt) = ScalarT(numFields, dof_value(cell, 0).val() * curl_basis(cell, 0, pt));
266 dof_curl(cell,pt).fastAccessDx(offsets[0]) = dof_value(cell, 0).fastAccessDx(offsets[0]) * curl_basis(cell, 0, pt);
267 for (
int bf=1; bf<numFields; bf++) {
268 dof_curl(cell,pt).val() += dof_value(cell, bf).val() * curl_basis(cell, bf, pt);
269 dof_curl(cell,pt).fastAccessDx(offsets[bf]) += dof_value(cell, bf).fastAccessDx(offsets[bf]) * curl_basis(cell, bf, pt);
285template<
typename EvalT,
typename TRAITS>
287DOFCurl(
const Teuchos::ParameterList & p) :
293 Teuchos::RCP<const PureBasis> basis
294 = p.get< Teuchos::RCP<BasisIRLayout> >(
"Basis")->getBasis();
297 TEUCHOS_TEST_FOR_EXCEPTION(!basis->supportsCurl(),std::logic_error,
298 "DOFCurl: Basis of type \"" << basis->name() <<
"\" does not support CURL");
299 TEUCHOS_TEST_FOR_EXCEPTION(!basis->requiresOrientations(),std::logic_error,
300 "DOFCurl: Basis of type \"" << basis->name() <<
"\" in DOF Curl should require orientations. So we are throwing.");
305 dof_curl_scalar = PHX::MDField<ScalarT,Cell,Point>(p.get<std::string>(
"Curl Name"),
306 p.get< Teuchos::RCP<panzer::IntegrationRule> >(
"IR")->dl_scalar );
310 dof_curl_vector = PHX::MDField<ScalarT,Cell,Point,Dim>(p.get<std::string>(
"Curl Name"),
311 p.get< Teuchos::RCP<panzer::IntegrationRule> >(
"IR")->dl_vector );
315 { TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
"DOFCurl only works for 2D and 3D basis functions"); }
325template<
typename EvalT,
typename TRAITS>
327DOFCurl(
const PHX::FieldTag & input,
328 const PHX::FieldTag & output,
337 TEUCHOS_ASSERT(
bd_.getType()==
"HCurl");
351 { TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
"DOFCurl only works for 2D and 3D basis functions"); }
361template<
typename EvalT,
typename TRAITS>
377template<
typename EvalT,
typename TRAITS>
386 Kokkos::parallel_for(workset.num_cells,functor);
390 Kokkos::parallel_for(workset.num_cells,functor);
401template<
typename TRAITS>
403DOFCurl(
const Teuchos::ParameterList & p) :
404 use_descriptors_(false),
405 dof_value( p.get<
std::string>(
"Name"),
409 Teuchos::RCP<const PureBasis> basis
410 = p.get< Teuchos::RCP<BasisIRLayout> >(
"Basis")->getBasis();
414 if(p.isType<Teuchos::RCP<
const std::vector<int> > >(
"Jacobian Offsets Vector")) {
415 offsets = *p.get<Teuchos::RCP<const std::vector<int> > >(
"Jacobian Offsets Vector");
418 PHX::View<int*> offsets_array_nc(
"offsets",offsets.size());
419 auto offsets_array_nc_h = Kokkos::create_mirror_view(offsets_array_nc);
420 for(std::size_t i=0;i<offsets.size();i++)
421 offsets_array_nc_h(i) = offsets[i];
422 Kokkos::deep_copy(offsets_array_nc, offsets_array_nc_h);
423 offsets_array = offsets_array_nc;
425 accelerate_jacobian = true;
428 accelerate_jacobian =
false;
431 TEUCHOS_TEST_FOR_EXCEPTION(!basis->supportsCurl(),std::logic_error,
432 "DOFCurl: Basis of type \"" << basis->name() <<
"\" does not support CURL");
433 TEUCHOS_TEST_FOR_EXCEPTION(!basis->requiresOrientations(),std::logic_error,
434 "DOFCurl: Basis of type \"" << basis->name() <<
"\" in DOF Curl should require orientations. So we are throwing.");
439 dof_curl_scalar = PHX::MDField<ScalarT,Cell,Point>(p.get<std::string>(
"Curl Name"),
440 p.get< Teuchos::RCP<panzer::IntegrationRule> >(
"IR")->dl_scalar );
441 this->addEvaluatedField(dof_curl_scalar);
444 dof_curl_vector = PHX::MDField<ScalarT,Cell,Point,Dim>(p.get<std::string>(
"Curl Name"),
445 p.get< Teuchos::RCP<panzer::IntegrationRule> >(
"IR")->dl_vector );
446 this->addEvaluatedField(dof_curl_vector);
449 { TEUCHOS_TEST_FOR_EXCEPTION(true,std::logic_error,
"DOFCurl only works for 2D and 3D basis functions"); }
459template<
typename TRAITS>
461DOFCurl(
const PHX::FieldTag & input,
462 const PHX::FieldTag & output,
466 : use_descriptors_(true)
475 accelerate_jacobian =
false;
487 { TEUCHOS_TEST_FOR_EXCEPTION(
true,std::logic_error,
"DOFCurl only works for 2D and 3D basis functions"); }
497template<
typename TRAITS>
500 PHX::FieldManager<TRAITS>& fm)
502 this->utils.setFieldData(dof_value,fm);
503 if(basis_dimension==3)
504 this->utils.setFieldData(dof_curl_vector,fm);
506 this->utils.setFieldData(dof_curl_scalar,fm);
508 if(not use_descriptors_)
512template<
typename TRAITS>
516 const panzer::BasisValues2<double> & basisValues = use_descriptors_ ? this->wda(workset).getBasisValues(bd_,id_)
517 : *this->wda(workset).bases[basis_index];
519 if(!accelerate_jacobian) {
520 if(basis_dimension==3) {
523 EvaluateCurlWithSens_Vector<ScalarT,Array,3> functor(dof_value,dof_curl_vector,curl_basis_vector);
524 Kokkos::parallel_for(workset.num_cells,functor);
529 EvaluateCurlWithSens_Scalar<ScalarT,Array> functor(dof_value,dof_curl_scalar,curl_basis_scalar);
530 Kokkos::parallel_for(workset.num_cells,functor);
537 if(basis_dimension==3) {
540 EvaluateCurlFastSens_Vector<ScalarT,Array,3> functor(dof_value,dof_curl_vector,offsets_array,curl_basis_vector);
541 Kokkos::parallel_for(workset.num_cells,functor);
546 EvaluateCurlFastSens_Scalar<ScalarT,Array> functor(dof_value,dof_curl_scalar,offsets_array,curl_basis_scalar);
547 Kokkos::parallel_for(workset.num_cells,functor);
const std::string & getType() const
Get type of basis.
PHX::MDField< const Scalar, Cell, BASIS, IP > ConstArray_CellBasisIP
Array_CellBasisIPDim curl_basis_vector
ConstArray_CellBasisIPDim getCurlVectorBasis(const bool weighted, const bool cache=true, const bool force=false) const
Get the curl of a 3D vector basis evaluated at mesh points.
Array_CellBasisIP curl_basis_scalar
PHX::MDField< const Scalar, Cell, BASIS, IP, Dim > ConstArray_CellBasisIPDim
ConstArray_CellBasisIP getCurl2DVectorBasis(const bool weighted, const bool cache=true, const bool force=false) const
Get the curl of a 2D vector basis evaluated at mesh points.
DOFCurl(const Teuchos::ParameterList &p)
PHX::MDField< ScalarT, Cell, Point > dof_curl_scalar
panzer::IntegrationDescriptor id_
void evaluateFields(typename TRAITS::EvalData d)
PHX::MDField< const ScalarT, Cell, Point > dof_value
void postRegistrationSetup(typename TRAITS::SetupData d, PHX::FieldManager< TRAITS > &fm)
panzer::BasisDescriptor bd_
PHX::MDField< ScalarT, Cell, Point, Dim > dof_curl_vector
WorksetDetailsAccessor wda
std::vector< std::string >::size_type getBasisIndex(std::string basis_name, const panzer::Workset &workset, WorksetDetailsAccessor &wda)
Returns the index in the workset bases for a particular BasisIRLayout name.