Panzer  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Panzer_DOFCurl_impl.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Panzer: A partial differential equation assembly
4 // engine for strongly coupled complex multiphysics systems
5 //
6 // Copyright 2011 NTESS and the Panzer contributors.
7 // SPDX-License-Identifier: BSD-3-Clause
8 // *****************************************************************************
9 // @HEADER
10 
11 #ifndef PANZER_DOF_CURL_IMPL_HPP
12 #define PANZER_DOF_CURL_IMPL_HPP
13 
15 #include "Panzer_BasisIRLayout.hpp"
17 #include "Intrepid2_FunctionSpaceTools.hpp"
18 #include "Phalanx_KokkosDeviceTypes.hpp"
19 
20 namespace panzer {
21 
22 namespace {
23 
24 //**********************************************************************
25 template <typename ScalarT,typename Array,int spaceDim>
26 class EvaluateCurlWithSens_Vector {
29  Array curl_basis;
30 
31  int numFields;
32  int numPoints;
33 
34 public:
35  typedef typename PHX::Device execution_space;
36 
37  EvaluateCurlWithSens_Vector(PHX::MDField<const ScalarT,Cell,Point> in_dof_value,
39  Array in_curl_basis)
40  : dof_value(in_dof_value), dof_curl(in_dof_curl), curl_basis(in_curl_basis)
41  {
42  numFields = curl_basis.extent(1);
43  numPoints = curl_basis.extent(2);
44  }
45  KOKKOS_INLINE_FUNCTION
46  void operator()(const unsigned int cell) const
47  {
48  for (int pt=0; pt<numPoints; pt++) {
49  for (int d=0; d<spaceDim; d++) {
50  // first initialize to the right thing (prevents over writing with 0)
51  // then loop over one less basis function
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);
55  }
56  }
57  }
58 };
59 
60 template <typename ScalarT,typename ArrayT>
61 void evaluateCurl_withSens_vector(int numCells,
64  const ArrayT & curl_basis)
65 {
66  if(numCells>0) {
67  // evaluate at quadrature points
68  int numFields = curl_basis.extent(1);
69  int numPoints = curl_basis.extent(2);
70  int spaceDim = curl_basis.extent(3);
71 
72  for (int cell=0; cell<numCells; cell++) {
73  for (int pt=0; pt<numPoints; pt++) {
74  for (int d=0; d<spaceDim; d++) {
75  // first initialize to the right thing (prevents over writing with 0)
76  // then loop over one less basis function
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);
80  }
81  }
82  }
83  }
84 }
85 
86 //**********************************************************************
87 template <typename ScalarT,typename Array>
88 class EvaluateCurlWithSens_Scalar {
91  Array curl_basis;
92 
93  int numFields;
94  int numPoints;
95 
96 public:
97  typedef typename PHX::Device execution_space;
98 
99  EvaluateCurlWithSens_Scalar(PHX::MDField<const ScalarT,Cell,Point> in_dof_value,
101  Array in_curl_basis)
102  : dof_value(in_dof_value), dof_curl(in_dof_curl), curl_basis(in_curl_basis)
103  {
104  numFields = curl_basis.extent(1);
105  numPoints = curl_basis.extent(2);
106  }
107  KOKKOS_INLINE_FUNCTION
108  void operator()(const unsigned int cell) const
109  {
110  for (int pt=0; pt<numPoints; pt++) {
111  // first initialize to the right thing (prevents over writing with 0)
112  // then loop over one less basis function
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);
116  }
117  }
118 };
119 
120 template <typename ScalarT,typename ArrayT>
121 void evaluateCurl_withSens_scalar(int numCells,
124  const ArrayT & curl_basis)
125 {
126  if(numCells>0) {
127  // evaluate at quadrature points
128  int numFields = curl_basis.extent(1);
129  int numPoints = curl_basis.extent(2);
130 
131  for (int cell=0; cell<numCells; cell++) {
132  for (int pt=0; pt<numPoints; pt++) {
133  // first initialize to the right thing (prevents over writing with 0)
134  // then loop over one less basis function
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);
138  }
139  }
140  }
141 }
142 
143 //**********************************************************************
144 template <typename ScalarT,typename Array,int spaceDim>
145 class EvaluateCurlFastSens_Vector {
148  PHX::View<const int*> offsets;
149  Array curl_basis;
150 
151  int numFields;
152  int numPoints;
153 
154 public:
155  typedef typename PHX::Device execution_space;
156 
157  EvaluateCurlFastSens_Vector(PHX::MDField<const ScalarT,Cell,Point> in_dof_value,
159  PHX::View<const int*> in_offsets,
160  Array in_curl_basis)
161  : dof_value(in_dof_value), dof_curl(in_dof_curl), offsets(in_offsets), curl_basis(in_curl_basis)
162  {
163  numFields = curl_basis.extent(1);
164  numPoints = curl_basis.extent(2);
165  }
166  KOKKOS_INLINE_FUNCTION
167  void operator()(const unsigned int cell) const
168  {
169  for (int pt=0; pt<numPoints; pt++) {
170  for (int d=0; d<spaceDim; d++) {
171  // first initialize to the right thing (prevents over writing with 0)
172  // then loop over one less basis function
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);
178  }
179  }
180  }
181  }
182 };
183 template <typename ScalarT,typename ArrayT>
184 void evaluateCurl_fastSens_vector(int numCells,
187  const std::vector<int> & offsets,
188  const ArrayT & curl_basis)
189 {
190  if(numCells>0) {
191  int numFields = curl_basis.extent(1);
192  int numPoints = curl_basis.extent(2);
193  int spaceDim = curl_basis.extent(3);
194 
195  for (int cell=0; cell<numCells; cell++) {
196  for (int pt=0; pt<numPoints; pt++) {
197  for (int d=0; d<spaceDim; d++) {
198  // first initialize to the right thing (prevents over writing with 0)
199  // then loop over one less basis function
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);
205  }
206  }
207  }
208  }
209  }
210 }
211 
212 //**********************************************************************
213 template <typename ScalarT,typename Array>
214 class EvaluateCurlFastSens_Scalar {
217  PHX::View<const int*> offsets;
218  Array curl_basis;
219 
220  int numFields;
221  int numPoints;
222 
223 public:
224  typedef typename PHX::Device execution_space;
225 
226  EvaluateCurlFastSens_Scalar(PHX::MDField<const ScalarT,Cell,Point> in_dof_value,
228  PHX::View<const int*> in_offsets,
229  Array in_curl_basis)
230  : dof_value(in_dof_value), dof_curl(in_dof_curl), offsets(in_offsets), curl_basis(in_curl_basis)
231  {
232  numFields = curl_basis.extent(1);
233  numPoints = curl_basis.extent(2);
234  }
235  KOKKOS_INLINE_FUNCTION
236  void operator()(const unsigned int cell) const
237  {
238  for (int pt=0; pt<numPoints; pt++) {
239  // first initialize to the right thing (prevents over writing with 0)
240  // then loop over one less basis function
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);
246  }
247  }
248  }
249 };
250 template <typename ScalarT,typename ArrayT>
251 void evaluateCurl_fastSens_scalar(int numCells,
254  const std::vector<int> & offsets,
255  const ArrayT & curl_basis)
256 {
257  if(numCells>0) {
258  int numFields = curl_basis.extent(1);
259  int numPoints = curl_basis.extent(2);
260 
261  for (int cell=0; cell<numCells; cell++) {
262  for (int pt=0; pt<numPoints; pt++) {
263  // first initialize to the right thing (prevents over writing with 0)
264  // then loop over one less basis function
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);
270  }
271  }
272  }
273  }
274 }
275 
276 //**********************************************************************
277 
278 }
279 
280 //**********************************************************************
281 // MOST EVALUATION TYPES
282 //**********************************************************************
283 
284 //**********************************************************************
285 template<typename EvalT, typename TRAITS>
288  use_descriptors_(false),
289  dof_value( p.get<std::string>("Name"),
290  p.get< Teuchos::RCP<panzer::BasisIRLayout> >("Basis")->functional),
291  basis_name(p.get< Teuchos::RCP<panzer::BasisIRLayout> >("Basis")->name())
292 {
294  = p.get< Teuchos::RCP<BasisIRLayout> >("Basis")->getBasis();
295 
296  // Verify that this basis supports the curl operation
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.");
301 
302  // build dof_curl
303  basis_dimension = basis->dimension();
304  if(basis_dimension==2) {
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 );
307  this->addEvaluatedField(dof_curl_scalar);
308  }
309  else if(basis_dimension==3) {
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 );
312  this->addEvaluatedField(dof_curl_vector);
313  }
314  else
315  { TEUCHOS_TEST_FOR_EXCEPTION(true,std::logic_error,"DOFCurl only works for 2D and 3D basis functions"); }
316 
317  // add to evaluation graph
318  this->addDependentField(dof_value);
319 
320  std::string n = "DOFCurl: " + (basis_dimension==2 ? dof_curl_scalar.fieldTag().name() : dof_curl_vector.fieldTag().name())+ " ()";
321  this->setName(n);
322 }
323 
324 //**********************************************************************
325 template<typename EvalT, typename TRAITS>
327 DOFCurl(const PHX::FieldTag & input,
328  const PHX::FieldTag & output,
329  const panzer::BasisDescriptor & bd,
331  int basis_dim)
332  : use_descriptors_(true)
333  , bd_(bd)
334  , id_(id)
335  , dof_value(input)
336 {
337  TEUCHOS_ASSERT(bd_.getType()=="HCurl");
338 
339  basis_dimension = basis_dim; // user specified
340 
341  // build dof_curl
342  if(basis_dimension==2) {
343  dof_curl_scalar = output;
344  this->addEvaluatedField(dof_curl_scalar);
345  }
346  else if(basis_dimension==3) {
347  dof_curl_vector = output;
348  this->addEvaluatedField(dof_curl_vector);
349  }
350  else
351  { TEUCHOS_TEST_FOR_EXCEPTION(true,std::logic_error,"DOFCurl only works for 2D and 3D basis functions"); }
352 
353  // add to evaluation graph
354  this->addDependentField(dof_value);
355 
356  std::string n = "DOFCurl: " + (basis_dimension==2 ? dof_curl_scalar.fieldTag().name() : dof_curl_vector.fieldTag().name())+ " ()";
357  this->setName(n);
358 }
359 
360 //**********************************************************************
361 template<typename EvalT, typename TRAITS>
363 postRegistrationSetup(typename TRAITS::SetupData sd,
365 {
366  this->utils.setFieldData(dof_value,fm);
367  if(basis_dimension==3)
368  this->utils.setFieldData(dof_curl_vector,fm);
369  else
370  this->utils.setFieldData(dof_curl_scalar,fm);
371 
372  if(not use_descriptors_)
373  basis_index = panzer::getBasisIndex(basis_name, (*sd.worksets_)[0], this->wda);
374 }
375 
376 //**********************************************************************
377 template<typename EvalT, typename TRAITS>
379 evaluateFields(typename TRAITS::EvalData workset)
380 {
381  const panzer::BasisValues2<double> & basisValues = use_descriptors_ ? this->wda(workset).getBasisValues(bd_,id_)
382  : *this->wda(workset).bases[basis_index];
383 
384  if(basis_dimension==3) {
385  EvaluateCurlWithSens_Vector<ScalarT,typename BasisValues2<double>::Array_CellBasisIPDim,3> functor(dof_value,dof_curl_vector,basisValues.curl_basis_vector);
386  Kokkos::parallel_for(workset.num_cells,functor);
387  }
388  else {
389  EvaluateCurlWithSens_Scalar<ScalarT,typename BasisValues2<double>::Array_CellBasisIP> functor(dof_value,dof_curl_scalar,basisValues.curl_basis_scalar);
390  Kokkos::parallel_for(workset.num_cells,functor);
391  }
392 }
393 
394 //**********************************************************************
395 
396 //**********************************************************************
397 // JACOBIAN EVALUATION TYPES
398 //**********************************************************************
399 
400 //**********************************************************************
401 template<typename TRAITS>
404  use_descriptors_(false),
405  dof_value( p.get<std::string>("Name"),
406  p.get< Teuchos::RCP<panzer::BasisIRLayout> >("Basis")->functional),
407  basis_name(p.get< Teuchos::RCP<panzer::BasisIRLayout> >("Basis")->name())
408 {
410  = p.get< Teuchos::RCP<BasisIRLayout> >("Basis")->getBasis();
411 
412  // do you specialize because you know where the basis functions are and can
413  // skip a large number of AD calculations?
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");
416 
417  // allocate and copy offsets vector to Kokkos array
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;
424 
425  accelerate_jacobian = true; // short cut for identity matrix
426  }
427  else
428  accelerate_jacobian = false; // don't short cut for identity matrix
429 
430  // Verify that this basis supports the curl operation
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.");
435 
436  // build dof_curl
437  basis_dimension = basis->dimension();
438  if(basis_dimension==2) {
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);
442  }
443  else if(basis_dimension==3) {
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);
447  }
448  else
449  { TEUCHOS_TEST_FOR_EXCEPTION(true,std::logic_error,"DOFCurl only works for 2D and 3D basis functions"); }
450 
451  // add to evaluation graph
452  this->addDependentField(dof_value);
453 
454  std::string n = "DOFCurl: " + (basis_dimension==2 ? dof_curl_scalar.fieldTag().name() : dof_curl_vector.fieldTag().name())+ " (Jacobian)";
455  this->setName(n);
456 }
457 
458 //**********************************************************************
459 template<typename TRAITS>
461 DOFCurl(const PHX::FieldTag & input,
462  const PHX::FieldTag & output,
463  const panzer::BasisDescriptor & bd,
465  int basis_dim)
466  : use_descriptors_(true)
467  , bd_(bd)
468  , id_(id)
469  , dof_value(input)
470 {
471  TEUCHOS_ASSERT(bd_.getType()=="HCurl");
472 
473  basis_dimension = basis_dim; // user specified
474 
475  accelerate_jacobian = false; // don't short cut for identity matrix
476 
477  // build dof_curl
478  if(basis_dimension==2) {
479  dof_curl_scalar = output;
480  this->addEvaluatedField(dof_curl_scalar);
481  }
482  else if(basis_dimension==3) {
483  dof_curl_vector = output;
484  this->addEvaluatedField(dof_curl_vector);
485  }
486  else
487  { TEUCHOS_TEST_FOR_EXCEPTION(true,std::logic_error,"DOFCurl only works for 2D and 3D basis functions"); }
488 
489  // add to evaluation graph
490  this->addDependentField(dof_value);
491 
492  std::string n = "DOFCurl: " + (basis_dimension==2 ? dof_curl_scalar.fieldTag().name() : dof_curl_vector.fieldTag().name())+ " (Jacobian)";
493  this->setName(n);
494 }
495 
496 //**********************************************************************
497 template<typename TRAITS>
499 postRegistrationSetup(typename TRAITS::SetupData sd,
501 {
502  this->utils.setFieldData(dof_value,fm);
503  if(basis_dimension==3)
504  this->utils.setFieldData(dof_curl_vector,fm);
505  else
506  this->utils.setFieldData(dof_curl_scalar,fm);
507 
508  if(not use_descriptors_)
509  basis_index = panzer::getBasisIndex(basis_name, (*sd.worksets_)[0], this->wda);
510 }
511 
512 template<typename TRAITS>
514 evaluateFields(typename TRAITS::EvalData workset)
515 {
516  const panzer::BasisValues2<double> & basisValues = use_descriptors_ ? this->wda(workset).getBasisValues(bd_,id_)
517  : *this->wda(workset).bases[basis_index];
518 
519  if(!accelerate_jacobian) {
520  if(basis_dimension==3) {
522  Array curl_basis_vector = use_descriptors_ ? basisValues.getCurlVectorBasis(false) : Array(basisValues.curl_basis_vector);
523  EvaluateCurlWithSens_Vector<ScalarT,Array,3> functor(dof_value,dof_curl_vector,curl_basis_vector);
524  Kokkos::parallel_for(workset.num_cells,functor);
525  }
526  else {
528  Array curl_basis_scalar = use_descriptors_ ? basisValues.getCurl2DVectorBasis(false) : Array(basisValues.curl_basis_scalar);
529  EvaluateCurlWithSens_Scalar<ScalarT,Array> functor(dof_value,dof_curl_scalar,curl_basis_scalar);
530  Kokkos::parallel_for(workset.num_cells,functor);
531  }
532 
533  return;
534  }
535  else {
536 
537  if(basis_dimension==3) {
539  Array curl_basis_vector = use_descriptors_ ? basisValues.getCurlVectorBasis(false) : Array(basisValues.curl_basis_vector);
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);
542  }
543  else {
545  Array curl_basis_scalar = use_descriptors_ ? basisValues.getCurl2DVectorBasis(false) : Array(basisValues.curl_basis_scalar);
546  EvaluateCurlFastSens_Scalar<ScalarT,Array> functor(dof_value,dof_curl_scalar,offsets_array,curl_basis_scalar);
547  Kokkos::parallel_for(workset.num_cells,functor);
548  }
549  }
550 }
551 
552 }
553 
554 #endif
std::string basis_name
void postRegistrationSetup(typename TRAITS::SetupData d, PHX::FieldManager< TRAITS > &fm)
panzer::BasisDescriptor bd_
T & get(const std::string &name, T def_value)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Array_CellBasisIPDim curl_basis_vector
int numPoints
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.
PHX::MDField< ScalarT, Cell, Point > dof_curl_scalar
int numFields
PHX::MDField< ScalarT, Cell, Point, Dim > dof_curl_vector
PHX::View< const int * > offsets
const std::string & getType() const
Get type of basis.
ConstArray_CellBasisIP getBasisValues(const bool weighted, const bool cache=true, const bool force=false) const
Get the basis values evaluated at mesh points.
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.
std::size_t basis_index
Array curl_basis
DOFCurl(const Teuchos::ParameterList &p)
panzer::IntegrationDescriptor id_
bool isType(const std::string &name) const
#define TEUCHOS_ASSERT(assertion_test)
void evaluateFields(typename TRAITS::EvalData d)
PHX::MDField< const ScalarT, Cell, Point > dof_value
PHX::MDField< ScalarT, Cell, Point, Dim > dof_curl
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.
Array_CellBasisIP curl_basis_scalar