Panzer  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Panzer_Integrator_GradBasisDotTensorTimesVector_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_Integrator_GradBasisDotTensorTimesVector_impl_hpp__
12 #define __Panzer_Integrator_GradBasisDotTensorTimesVector_impl_hpp__
13 
15 //
16 // Include Files
17 //
19 
20 // Panzer
21 #include "Panzer_BasisIRLayout.hpp"
25 
26 namespace panzer
27 {
29  //
30  // Main Constructor
31  //
33  template<typename EvalT, typename Traits>
37  const std::string& resName,
38  const std::string& fluxName,
39  const panzer::BasisIRLayout& basis,
40  const panzer::IntegrationRule& ir,
41  const std::string& tensorName,
42  const Teuchos::RCP<PHX::DataLayout>& vecDL /* = Teuchos::null */)
43  :
44  evalStyle_(evalStyle),
45  basisName_(basis.name())
46  {
47  using PHX::View;
48  using panzer::BASIS;
49  using panzer::Cell;
51  using panzer::IP;
52  using PHX::DataLayout;
53  using PHX::MDField;
54  using std::invalid_argument;
55  using std::logic_error;
56  using std::string;
57  using Teuchos::RCP;
58 
59  // Ensure the input makes sense.
60  TEUCHOS_TEST_FOR_EXCEPTION(resName == "", invalid_argument, "Error: " \
61  "Integrator_GradBasisDotTensorTimesVector called with an empty residual name.")
62  TEUCHOS_TEST_FOR_EXCEPTION(fluxName == "", invalid_argument, "Error: " \
63  "Integrator_GradBasisDotTensorTimesVector called with an empty flux name.")
64  RCP<const PureBasis> tmpBasis = basis.getBasis();
65  TEUCHOS_TEST_FOR_EXCEPTION(not tmpBasis->supportsGrad(), logic_error,
66  "Error: Integrator_GradBasisDotTensorTimesVector: Basis of type \""
67  << tmpBasis->name() << "\" does not support the gradient operator.")
68  RCP<DataLayout> tmpVecDL = ir.dl_vector;
69  if (not vecDL.is_null())
70  {
71  tmpVecDL = vecDL;
73  tmpVecDL->extent(2) < ir.dl_vector->extent(2), logic_error,
74  "Integrator_GradBasisDotTensorTimesVector: Dimension of space exceeds " \
75  "dimension of Vector Data Layout.");
76  } // end if (not vecDL.is_null())
77 
78  // Create the field for the vector-valued function we're integrating.
79  vector_ = MDField<const ScalarT, Cell, IP, Dim>(fluxName, tmpVecDL);
80  this->addDependentField(vector_);
81 
82  // Create the field that we're either contributing to or evaluating
83  // (storing).
84  field_ = MDField<ScalarT, Cell, BASIS>(resName, basis.functional);
86  this->addContributedField(field_);
87  else // if (evalStyle_ == EvaluatorStyle::EVALUATES)
88  this->addEvaluatedField(field_);
89 
90  // Add the tensor.
91  tensor_ = MDField<const ScalarT, Cell, IP, Dim, Dim>(tensorName, ir.dl_tensor);
92  this->addDependentField(tensor_);
93 
94  // Set the name of this object.
95  string n("Integrator_GradBasisDotTensorTimesVector (");
97  n += "CONTRIBUTES";
98  else // if (evalStyle_ == EvaluatorStyle::EVALUATES)
99  n += "EVALUATES";
100  n += "): " + field_.fieldTag().name();
101  this->setName(n);
102  } // end of Main Constructor
103 
105  //
106  // ParameterList Constructor
107  //
109  template<typename EvalT, typename Traits>
112  const Teuchos::ParameterList& p)
113  :
115  panzer::EvaluatorStyle::EVALUATES,
116  p.get<std::string>("Residual Name"),
117  p.get<std::string>("Flux Name"),
118  (*p.get<Teuchos::RCP<panzer::BasisIRLayout>>("Basis")),
119  (*p.get<Teuchos::RCP<panzer::IntegrationRule>>("IR")),
120  p.get<std::string>("Tensor Name"),
121  p.isType<Teuchos::RCP<PHX::DataLayout>>("Vector Data Layout") ?
122  p.get<Teuchos::RCP<PHX::DataLayout>>("Vector Data Layout") :
123  Teuchos::null)
124  {
126  using Teuchos::RCP;
127 
128  // Ensure that the input ParameterList didn't contain any bogus entries.
129  RCP<ParameterList> validParams = this->getValidParameters();
130  p.validateParameters(*validParams);
131  } // end of ParameterList Constructor
132 
134  //
135  // postRegistrationSetup()
136  //
138  template<typename EvalT, typename Traits>
139  void
142  typename Traits::SetupData sd,
143  PHX::FieldManager<Traits>& /* fm */)
144  {
145  using panzer::getBasisIndex;
146  using std::size_t;
147 
148  // Get the PHX::View of the tensor.
149  kokkosTensor_ = tensor_.get_static_view();
150 
151  // Determine the index in the Workset bases for our particular basis name.
152  basisIndex_ = getBasisIndex(basisName_, (*sd.worksets_)[0], this->wda);
153 
154  // Allocate temporary if not using shared memory
155  bool use_shared_memory = panzer::HP::inst().useSharedMemory<ScalarT>();
156  if (!use_shared_memory) {
157  if (Sacado::IsADType<ScalarT>::value) {
158  const auto fadSize = Kokkos::dimension_scalar(field_.get_view());
159  tmp_ = PHX::View<ScalarT*>("GradBasisDotTensorTimesVector::tmp_",field_.extent(0),fadSize);
160  } else {
161  tmp_ = PHX::View<ScalarT*>("GradBasisDotTensorTimesVector::tmp_",field_.extent(0));
162  }
163  }
164  } // end of postRegistrationSetup()
165 
167  //
168  // operator()() NO shared memory
169  //
171  template<typename EvalT, typename Traits>
172  KOKKOS_INLINE_FUNCTION
173  void
176  const FieldMultTag& /* tag */,
177  const Kokkos::TeamPolicy<PHX::exec_space>::member_type& team) const
178  {
180  const int cell = team.league_rank();
181 
182  // Initialize the evaluated field.
183  const int numQP(vector_.extent(1)), numDim(vector_.extent(2)),
184  numBases(basis_.extent(1));
185  if (evalStyle_ == EvaluatorStyle::EVALUATES)
186  Kokkos::parallel_for(Kokkos::TeamThreadRange(team,0,numBases), [&] (const int basis) {
187  field_(cell, basis) = 0.0;
188  });
189 
190  {
191  // Loop over the quadrature points and dimensions of our vector fields,
192  // scale the integrand by the multiplier, and then perform the
193  // integration, looping over the bases.
194  for (int qp(0); qp < numQP; ++qp)
195  {
196  for (int dim(0); dim < numDim; ++dim)
197  {
198  tmp_(cell) = 0.0;
199  for (int dim2(0); dim2 < numDim; ++dim2)
200  tmp_(cell) += kokkosTensor_(cell, qp, dim, dim2) * vector_(cell, qp, dim2);
201  Kokkos::parallel_for(Kokkos::TeamThreadRange(team,0,numBases), [&] (const int basis) {
202  field_(cell, basis) += basis_(cell, basis, qp, dim) * tmp_(cell);
203  });
204  } // end loop over the dimensions of the vector field
205  } // end loop over the quadrature points
206  }
207  } // end of operator()()
208 
210  //
211  // operator()() With shared memory
212  //
214  template<typename EvalT, typename Traits>
215  KOKKOS_INLINE_FUNCTION
216  void
219  const SharedFieldMultTag& /* tag */,
220  const Kokkos::TeamPolicy<PHX::exec_space>::member_type& team) const
221  {
223  const int cell = team.league_rank();
224  const int numQP = vector_.extent(1);
225  const int numDim = vector_.extent(2);
226  const int numBases = basis_.extent(1);
227  const int fadSize = Kokkos::dimension_scalar(field_.get_view());
228 
229  scratch_view tmp;
230  scratch_view tmp_field;
231  if (Sacado::IsADType<ScalarT>::value) {
232  tmp = scratch_view(team.team_shmem(),1,fadSize);
233  tmp_field = scratch_view(team.team_shmem(),numBases,fadSize);
234  }
235  else {
236  tmp = scratch_view(team.team_shmem(),1);
237  tmp_field = scratch_view(team.team_shmem(),numBases);
238  }
239 
240  // Initialize the evaluated field.
241  Kokkos::parallel_for(Kokkos::TeamThreadRange(team,0,numBases), [&] (const int basis) {
242  tmp_field(basis) = 0.0;
243  });
244 
245  {
246  // Loop over the quadrature points and dimensions of our vector fields,
247  // scale the integrand by the multiplier, and then perform the
248  // integration, looping over the bases.
249  for (int qp(0); qp < numQP; ++qp)
250  {
251  for (int dim(0); dim < numDim; ++dim)
252  {
253  tmp_(cell) = 0.0;
254  for (int dim2(0); dim2 < numDim; ++dim2)
255  tmp_(cell) += kokkosTensor_(cell, qp, dim, dim2) * vector_(cell, qp, dim2);
256  Kokkos::parallel_for(Kokkos::TeamThreadRange(team,0,numBases), [&] (const int basis) {
257  tmp_field(basis) += basis_(cell, basis, qp, dim) * tmp_(cell);
258  });
259  } // end loop over the dimensions of the vector field
260  } // end loop over the quadrature points
261  }
262 
263  // Put final values into target field
264  if (evalStyle_ == EvaluatorStyle::EVALUATES) {
265  Kokkos::parallel_for(Kokkos::TeamThreadRange(team,0,numBases),[&] (const int basis) {
266  field_(cell,basis) = tmp_field(basis);
267  });
268  }
269  else { // Contributed
270  Kokkos::parallel_for(Kokkos::TeamThreadRange(team,0,numBases),[&] (const int basis) {
271  field_(cell,basis) += tmp_field(basis);
272  });
273  }
274 
275  } // end of operator()()
276 
278  //
279  // evaluateFields()
280  //
282  template<typename EvalT, typename Traits>
283  void
286  typename Traits::EvalData workset)
287  {
288  using Kokkos::parallel_for;
289  using Kokkos::TeamPolicy;
290 
291  // Grab the basis information.
292  basis_ = this->wda(workset).bases[basisIndex_]->weighted_grad_basis;
293 
294  bool use_shared_memory = panzer::HP::inst().useSharedMemory<ScalarT>();
295  if (use_shared_memory) {
296  int bytes;
297  if (Sacado::IsADType<ScalarT>::value) {
298  const int fadSize = Kokkos::dimension_scalar(field_.get_view());
299  bytes = scratch_view::shmem_size(1,fadSize) + scratch_view::shmem_size(basis_.extent(1),fadSize);
300  }
301  else
302  bytes = scratch_view::shmem_size(1) + scratch_view::shmem_size(basis_.extent(1));
303 
304  auto policy = panzer::HP::inst().teamPolicy<ScalarT,SharedFieldMultTag,PHX::Device>(workset.num_cells).set_scratch_size(0,Kokkos::PerTeam(bytes));
305  parallel_for(this->getName(), policy, *this);
306  }
307  else {
308  auto policy = panzer::HP::inst().teamPolicy<ScalarT,FieldMultTag,PHX::Device>(workset.num_cells);
309  parallel_for(this->getName(), policy, *this);
310  }
311  } // end of evaluateFields()
312 
314  //
315  // getValidParameters()
316  //
318  template<typename EvalT, typename TRAITS>
322  {
323  using panzer::BasisIRLayout;
325  using PHX::DataLayout;
326  using std::string;
327  using std::vector;
329  using Teuchos::RCP;
330  using Teuchos::rcp;
331 
332  // Create a ParameterList with all the valid keys we support.
333  RCP<ParameterList> p = rcp(new ParameterList);
334  p->set<string>("Residual Name", "?");
335  p->set<string>("Flux Name", "?");
336  RCP<BasisIRLayout> basis;
337  p->set("Basis", basis);
339  p->set("IR", ir);
340  p->set<std::string>("Tensor Name", "?");
341  RCP<DataLayout> vecDL;
342  p->set("Vector Data Layout", vecDL);
343  return p;
344  } // end of getValidParameters()
345 
346 } // end of namespace panzer
347 
348 #endif // __Panzer_Integrator_GradBasisDotTensorTimesVector_impl_hpp__
int num_cells
DEPRECATED - use: numCells()
This empty struct allows us to optimize operator()() depending on the number of field multipliers...
Kokkos::TeamPolicy< TeamPolicyProperties...> teamPolicy(const int &league_size)
Returns a TeamPolicy for hierarchic parallelism.
Teuchos::RCP< PHX::DataLayout > dl_tensor
Data layout for rank-2 tensor fields.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
KOKKOS_INLINE_FUNCTION void operator()(const FieldMultTag &tag, const Kokkos::TeamPolicy< PHX::exec_space >::member_type &team) const
Perform the integration.
PHX::MDField< const ScalarT, panzer::Cell, panzer::IP, panzer::Dim, panzer::Dim > tensor_
The tensor field( ).
EvaluatorStyle
An indication of how an Evaluator will behave.
Teuchos::RCP< const PureBasis > getBasis() const
void postRegistrationSetup(typename Traits::SetupData d, PHX::FieldManager< Traits > &fm)
Post-Registration Setup.
Teuchos::RCP< Teuchos::ParameterList > getValidParameters() const
Get Valid Parameters.
PHX::MDField< ScalarT, panzer::Cell, panzer::BASIS > field_
A field to which we&#39;ll contribute, or in which we&#39;ll store, the result of computing this integral...
Integrator_GradBasisDotTensorTimesVector(const panzer::EvaluatorStyle &evalStyle, const std::string &resName, const std::string &fluxName, const panzer::BasisIRLayout &basis, const panzer::IntegrationRule &ir, const std::string &tensorName, const Teuchos::RCP< PHX::DataLayout > &vecDL=Teuchos::null)
Main Constructor.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
panzer::EvaluatorStyle evalStyle
The EvaluatorStyle of the parent Integrator_CurlBasisDotVector object.
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.
PHX::MDField< const ScalarT, panzer::Cell, panzer::IP, panzer::Dim > vector_
A field representing the vector-valued function we&#39;re integrating ( ).
void validateParameters(ParameterList const &validParamList, int const depth=1000, EValidateUsed const validateUsed=VALIDATE_USED_ENABLED, EValidateDefaults const validateDefaults=VALIDATE_DEFAULTS_ENABLED) const
const panzer::EvaluatorStyle evalStyle_
An enum determining the behavior of this Evaluator.
This empty struct allows us to optimize operator()() depending on the number of field multipliers...
Teuchos::RCP< PHX::DataLayout > dl_vector
Data layout for vector fields.
static HP & inst()
Private ctor.
Teuchos::RCP< PHX::DataLayout > functional
&lt;Cell,Basis&gt;
Teuchos::RCP< const std::vector< panzer::Workset > > worksets_
bool is_null() const