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
51 evalStyle_(evalStyle),
52 multiplier_(multiplier),
53 basisName_(basis.name())
62 using std::invalid_argument;
63 using std::logic_error;
69 "Integrator_DivBasisTimesScalar called with an empty residual name.")
71 "Integrator_DivBasisTimesScalar called with an empty value name.")
74 "Error: Integrator_DivBasisTimesScalar: Basis of type \""
75 << tmpBasis->name() <<
"\" does not support DIV.")
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>
126 p.get<std::string>(
"Residual Name"),
127 p.get<std::string>(
"Value Name"),
130 p.get<double>(
"Multiplier"),
131 p.isType<Teuchos::
RCP<
const std::vector<std::string>>>
132 (
"Field Multipliers") ?
133 (*p.get<Teuchos::
RCP<
const std::vector<std::string>>>
134 (
"Field Multipliers")) : std::vector<std::string>())
149 template<
typename EvalT,
typename Traits>
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>
431 p->set<
string>(
"Residual Name",
"?");
432 p->set<
string>(
"Value Name",
"?");
433 p->set<
string>(
"Test Field Name",
"?");
435 p->set(
"Basis", basis);
438 p->set<
double>(
"Multiplier", 1.0);
440 p->set(
"Field Multipliers", fms);
446 #endif // __Panzer_Integrator_DivBasisTimesScalar_impl_hpp__
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.
int num_cells
DEPRECATED - use: numCells()
void evaluateFields(typename Traits::EvalData d)
Evaluate Fields.
Kokkos::TeamPolicy< TeamPolicyProperties...> teamPolicy(const int &league_size)
Returns a TeamPolicy for hierarchic parallelism.
typename EvalT::ScalarT ScalarT
The scalar type.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
EvaluatorStyle
An indication of how an Evaluator will behave.
Teuchos::RCP< const PureBasis > getBasis() const
const panzer::EvaluatorStyle evalStyle_
An enum determining the behavior of this Evaluator.
double multiplier
The scalar multiplier out in front of the integral ( ).
PHX::MDField< const ScalarT, Cell, IP > scalar_
A field representing the scalar function we're integrating ( ).
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Teuchos::RCP< PHX::DataLayout > dl_scalar
Data layout for scalar fields.
panzer::EvaluatorStyle evalStyle
The EvaluatorStyle of the parent Integrator_CurlBasisDotVector object.
This empty struct allows us to optimize operator()() depending on the number of field multipliers...
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.
bool useSharedMemory() const
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< ScalarT, Cell, BASIS > field_
A field to which we'll contribute, or in which we'll store, the result of computing this integral...
Teuchos::RCP< Teuchos::ParameterList > getValidParameters() const
Get Valid Parameters.
void validateParameters(ParameterList const &validParamList, int const depth=1000, EValidateUsed const validateUsed=VALIDATE_USED_ENABLED, EValidateDefaults const validateDefaults=VALIDATE_DEFAULTS_ENABLED) const
void postRegistrationSetup(typename Traits::SetupData d, PHX::FieldManager< Traits > &fm)
Post-Registration Setup.
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.
static HP & inst()
Private ctor.
const std::vector< std::pair< int, LocalOrdinal > > &pid_and_lid const
Description and data layouts associated with a particular basis.
PHX::View< PHX::UnmanagedView< const ScalarT ** > * > kokkosFieldMults_
The PHX::View representation of the (possibly empty) list of fields that are multipliers out in front...
This empty struct allows us to optimize operator()() depending on the number of field multipliers...
Teuchos::RCP< PHX::DataLayout > functional
<Cell,Basis>
Teuchos::RCP< const std::vector< panzer::Workset > > worksets_
std::vector< PHX::MDField< const ScalarT, Cell, IP > > fieldMults_
The (possibly empty) list of fields that are multipliers out in front of the integral ( ...