11#ifndef __Panzer_Integrator_DivBasisTimesScalar_impl_hpp__
12#define __Panzer_Integrator_DivBasisTimesScalar_impl_hpp__
21#include "Intrepid2_FunctionSpaceTools.hpp"
24#include "Kokkos_ViewFactory.hpp"
39 template<
typename EvalT,
typename Traits>
43 const std::string& resName,
44 const std::string& valName,
48 const std::vector<std::string>& fmNames
53 basisName_(basis.name())
62 using std::invalid_argument;
63 using std::logic_error;
68 TEUCHOS_TEST_FOR_EXCEPTION(resName ==
"", invalid_argument,
"Error: " \
69 "Integrator_DivBasisTimesScalar called with an empty residual name.")
70 TEUCHOS_TEST_FOR_EXCEPTION(valName ==
"", invalid_argument,
"Error: " \
71 "Integrator_DivBasisTimesScalar called with an empty value name.")
72 RCP<const PureBasis> tmpBasis = basis.
getBasis();
73 TEUCHOS_TEST_FOR_EXCEPTION(not tmpBasis->supportsDiv(), logic_error,
74 "Error: Integrator_DivBasisTimesScalar: Basis of type \""
75 << tmpBasis->name() <<
"\" does not support DIV.")
76 TEUCHOS_TEST_FOR_EXCEPTION(not tmpBasis->requiresOrientations(), logic_error,
77 "Error: Integration_DivBasisTimesScalar: Basis of type \""
78 << tmpBasis->name() <<
"\" should require orientations.")
82 this->addDependentField(
scalar_);
88 this->addContributedField(
field_);
90 this->addEvaluatedField(
field_);
96 View<PHX::UnmanagedView<const ScalarT**>*>(
"DivBasisTimesScalar::KokkosFieldMultipliers",
98 for (
const auto& name : fmNames)
105 string n(
"Integrator_DivBasisTimesScalar (");
110 n +=
"): " +
field_.fieldTag().name();
119 template<
typename EvalT,
typename Traits>
122 const Teuchos::ParameterList& p)
126 p.get<
std::string>(
"Residual Name"),
127 p.get<
std::string>(
"Value Name"),
130 p.get<double>(
"Multiplier"),
132 (
"Field Multipliers") ?
134 (
"Field Multipliers")) :
std::vector<
std::string>())
136 using Teuchos::ParameterList;
141 p.validateParameters(*validParams);
149 template<
typename EvalT,
typename Traits>
156 using Kokkos::createDynRankView;
159 auto kokkosFieldMults_h = Kokkos::create_mirror_view(kokkosFieldMults_);
162 for (
size_t i(0); i < fieldMults_.size(); ++i)
163 kokkosFieldMults_h(i) = fieldMults_[i].get_static_view();
165 Kokkos::deep_copy(kokkosFieldMults_, kokkosFieldMults_h);
169 if (!use_shared_memory) {
170 if (Sacado::IsADType<ScalarT>::value) {
171 const auto fadSize = Kokkos::dimension_scalar(field_.get_view());
172 tmp_ = PHX::View<ScalarT*>(
"panzer::Integrator::DivBasisTimesScalar::tmp_",field_.extent(0),fadSize);
174 tmp_ = PHX::View<ScalarT*>(
"panzer::Integrator::DivBasisTimesScalar::tmp_",field_.extent(0));
187 template<
typename EvalT,
typename Traits>
188 template<
int NUM_FIELD_MULT>
189 KOKKOS_INLINE_FUNCTION
194 const Kokkos::TeamPolicy<PHX::exec_space>::member_type& team)
const
197 const int cell = team.league_rank();
200 const int numQP(scalar_.extent(1)), numBases(basis_.extent(1));
202 Kokkos::parallel_for(Kokkos::TeamThreadRange(team,0,numBases), [&] (
const int basis) {
203 field_(cell, basis) = 0.0;
209 if (NUM_FIELD_MULT == 0)
214 for (
int qp(0); qp < numQP; ++qp)
216 Kokkos::parallel_for(Kokkos::TeamThreadRange(team,0,numBases), [&] (
const int basis) {
217 field_(cell, basis) += basis_(cell, basis, qp) * multiplier_ * scalar_(cell, qp);
221 else if (NUM_FIELD_MULT == 1)
226 for (
int qp(0); qp < numQP; ++qp)
228 Kokkos::parallel_for(Kokkos::TeamThreadRange(team,0,numBases), [&] (
const int basis) {
229 field_(cell, basis) += basis_(cell, basis, qp) * multiplier_ * scalar_(cell, qp) * kokkosFieldMults_(0)(cell, qp);
239 const int numFieldMults(kokkosFieldMults_.extent(0));
240 for (
int qp(0); qp < numQP; ++qp)
244 for (
int fm(0); fm < numFieldMults; ++fm)
245 tmp_(cell) *= kokkosFieldMults_(fm)(cell, qp);
246 Kokkos::parallel_for(Kokkos::TeamThreadRange(team,0,numBases),[&] (
const int& basis) {
247 field_(cell, basis) += basis_(cell, basis, qp) * multiplier_ * scalar_(cell, qp) * tmp_(cell);
258 template<
typename EvalT,
typename Traits>
259 template<
int NUM_FIELD_MULT>
260 KOKKOS_INLINE_FUNCTION
265 const Kokkos::TeamPolicy<PHX::exec_space>::member_type& team)
const
268 const int cell = team.league_rank();
269 const int numQP = scalar_.extent(1);
270 const int numBases = basis_.extent(1);
271 const int fadSize = Kokkos::dimension_scalar(field_.get_view());
275 if (Sacado::IsADType<ScalarT>::value) {
277 tmp_field =
scratch_view(team.team_shmem(),numBases,fadSize);
285 Kokkos::parallel_for(Kokkos::TeamThreadRange(team,0,numBases),[&] (
const int& basis) {
286 tmp_field(basis) = 0.0;
291 if (NUM_FIELD_MULT == 0)
296 for (
int qp(0); qp < numQP; ++qp)
299 tmp(0) = multiplier_ * scalar_(cell, qp);
300 Kokkos::parallel_for(Kokkos::TeamThreadRange(team,0,numBases),[&] (
const int& basis) {
301 tmp_field(basis) += basis_(cell, basis, qp) * tmp(0);
305 else if (NUM_FIELD_MULT == 1)
310 for (
int qp(0); qp < numQP; ++qp)
313 tmp(0) = multiplier_ * scalar_(cell, qp) * kokkosFieldMults_(0)(cell, qp);
314 Kokkos::parallel_for(Kokkos::TeamThreadRange(team,0,numBases),[&] (
const int& basis) {
315 tmp_field(basis) += basis_(cell, basis, qp) * tmp(0);
325 const int numFieldMults = kokkosFieldMults_.extent(0);
326 for (
int qp(0); qp < numQP; ++qp)
330 for (
int fm(0); fm < numFieldMults; ++fm)
331 fieldMultsTotal *= kokkosFieldMults_(fm)(cell, qp);
332 tmp(0) = multiplier_ * scalar_(cell, qp) * fieldMultsTotal;
333 Kokkos::parallel_for(Kokkos::TeamThreadRange(team,0,numBases),[&] (
const int& basis) {
334 tmp_field(basis) += basis_(cell, basis, qp) * tmp(0);
341 Kokkos::parallel_for(Kokkos::TeamThreadRange(team,0,numBases),[&] (
const int& basis) {
342 field_(cell,basis) = tmp_field(basis);
346 Kokkos::parallel_for(Kokkos::TeamThreadRange(team,0,numBases),[&] (
const int& basis) {
347 field_(cell,basis) += tmp_field(basis);
358 template<
typename EvalT,
typename Traits>
364 using Kokkos::parallel_for;
365 using Kokkos::TeamPolicy;
368 basis_ = this->wda(workset).bases[basisIndex_]->weighted_div_basis;
372 if (use_shared_memory) {
374 if (Sacado::IsADType<ScalarT>::value) {
375 const int fadSize = Kokkos::dimension_scalar(field_.get_view());
376 bytes = scratch_view::shmem_size(1,fadSize) + scratch_view::shmem_size(basis_.extent(1),fadSize);
379 bytes = scratch_view::shmem_size(1) + scratch_view::shmem_size(basis_.extent(1));
384 if (fieldMults_.size() == 0) {
386 parallel_for(this->getName(), policy, *
this);
387 }
else if (fieldMults_.size() == 1) {
389 parallel_for(this->getName(), policy, *
this);
392 parallel_for(this->getName(), policy, *
this);
399 if (fieldMults_.size() == 0) {
401 parallel_for(this->getName(), policy, *
this);
402 }
else if (fieldMults_.size() == 1) {
404 parallel_for(this->getName(), policy, *
this);
407 parallel_for(this->getName(), policy, *
this);
417 template<
typename EvalT,
typename TRAITS>
418 Teuchos::RCP<Teuchos::ParameterList>
425 using Teuchos::ParameterList;
430 RCP<ParameterList> p = rcp(
new ParameterList);
431 p->set<
string>(
"Residual Name",
"?");
432 p->set<
string>(
"Value Name",
"?");
433 p->set<
string>(
"Test Field Name",
"?");
434 RCP<BasisIRLayout> basis;
435 p->set(
"Basis", basis);
436 RCP<IntegrationRule> ir;
438 p->set<
double>(
"Multiplier", 1.0);
439 RCP<const vector<string>> fms;
440 p->set(
"Field Multipliers", fms);
panzer::EvaluatorStyle evalStyle
The EvaluatorStyle of the parent Integrator_CurlBasisDotVector object.
double multiplier
The scalar multiplier out in front of the integral ( ).
Teuchos::RCP< PHX::DataLayout > functional
<Cell,Basis>
Teuchos::RCP< const PureBasis > getBasis() const
static HP & inst()
Private ctor.
bool useSharedMemory() const
Kokkos::TeamPolicy< TeamPolicyProperties... > teamPolicy(const int &league_size)
Returns a TeamPolicy for hierarchic parallelism.
PHX::MDField< const ScalarT, Cell, IP > scalar_
A field representing the scalar function we're integrating ( ).
Teuchos::RCP< Teuchos::ParameterList > getValidParameters() const
Get Valid Parameters.
KOKKOS_INLINE_FUNCTION void operator()(const FieldMultTag< NUM_FIELD_MULT > &tag, const Kokkos::TeamPolicy< PHX::exec_space >::member_type &team) const
Perform the integration. Main memory version.
Integrator_DivBasisTimesScalar(const panzer::EvaluatorStyle &evalStyle, const std::string &resName, const std::string &valName, const panzer::BasisIRLayout &basis, const panzer::IntegrationRule &ir, const double &multiplier=1, const std::vector< std::string > &fmNames=std::vector< std::string >())
Main Constructor.
void postRegistrationSetup(typename Traits::SetupData d, PHX::FieldManager< Traits > &fm)
Post-Registration Setup.
Kokkos::View< ScalarT *,typename PHX::DevLayout< ScalarT >::type, typename PHX::exec_space::scratch_memory_space, Kokkos::MemoryUnmanaged > scratch_view
Type for shared memory.
void evaluateFields(typename Traits::EvalData d)
Evaluate Fields.
const panzer::EvaluatorStyle evalStyle_
An enum determining the behavior of this Evaluator.
PHX::MDField< ScalarT, Cell, BASIS > field_
A field to which we'll contribute, or in which we'll store, the result of computing this integral.
PHX::View< PHX::UnmanagedView< const ScalarT ** > * > kokkosFieldMults_
The PHX::View representation of the (possibly empty) list of fields that are multipliers out in front...
typename EvalT::ScalarT ScalarT
The scalar type.
std::vector< PHX::MDField< const ScalarT, Cell, IP > > fieldMults_
The (possibly empty) list of fields that are multipliers out in front of the integral ( ,...
Teuchos::RCP< PHX::DataLayout > dl_scalar
Data layout for scalar fields.
Description and data layouts associated with a particular basis.
int num_cells
DEPRECATED - use: numCells()
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.
EvaluatorStyle
An indication of how an Evaluator will behave.
This empty struct allows us to optimize operator()() depending on the number of field multipliers.
This empty struct allows us to optimize operator()() depending on the number of field multipliers.
User-defined data passed to PHX::Evaluator::postRegistrationSetup() during the one-time setup phase.
Teuchos::RCP< const std::vector< panzer::Workset > > worksets_
All worksets that will be evaluated over the lifetime of this evaluator.