11#ifndef __Panzer_Integrator_GradBasisDotVector_impl_hpp__
12#define __Panzer_Integrator_GradBasisDotVector_impl_hpp__
33 template<
typename EvalT,
typename Traits>
37 const std::string& resName,
38 const std::string& fluxName,
41 const double& multiplier,
42 const std::vector<std::string>& fmNames,
44 const Teuchos::RCP<PHX::DataLayout>& vecDL )
55 using PHX::DataLayout;
57 using std::invalid_argument;
58 using std::logic_error;
63 TEUCHOS_TEST_FOR_EXCEPTION(resName ==
"", invalid_argument,
"Error: " \
64 "Integrator_GradBasisDotVector called with an empty residual name.")
65 TEUCHOS_TEST_FOR_EXCEPTION(fluxName ==
"", invalid_argument,
"Error: " \
66 "Integrator_GradBasisDotVector called with an empty flux name.")
67 RCP<const PureBasis> tmpBasis = basis.
getBasis();
68 TEUCHOS_TEST_FOR_EXCEPTION(not tmpBasis->supportsGrad(), logic_error,
69 "Error: Integrator_GradBasisDotVector: Basis of type \""
70 << tmpBasis->name() <<
"\" does not support the gradient operator.")
72 if (not vecDL.is_null())
75 TEUCHOS_TEST_FOR_EXCEPTION(
76 tmpVecDL->extent(2) < ir.
dl_vector->extent(2), logic_error,
77 "Integrator_GradBasisDotVector: Dimension of space exceeds " \
78 "dimension of Vector Data Layout.");
82 vector_ = MDField<const ScalarT, Cell, IP, Dim>(fluxName, tmpVecDL);
83 this->addDependentField(
vector_);
89 this->addContributedField(
field_);
91 this->addEvaluatedField(
field_);
96 kokkosFieldMults_ = PHX::View<PHX::UnmanagedView<const ScalarT**>*>(
"GradBasisDotVector::KokkosFieldMultipliers",
98 for (
const auto& name : fmNames)
105 string n(
"Integrator_GradBasisDotVector (");
110 n +=
"): " +
field_.fieldTag().name();
119 template<
typename EvalT,
typename Traits>
125 p.get<
std::string>(
"Residual Name"),
126 p.get<
std::string>(
"Flux Name"),
129 p.get<double>(
"Multiplier"),
131 (
"Field Multipliers") ?
133 (
"Field Multipliers")) :
std::vector<
std::string>(),
134 p.isType<
Teuchos::RCP<
PHX::DataLayout>>(
"Vector Data Layout") ?
135 p.get<
Teuchos::RCP<
PHX::DataLayout>>(
"Vector Data Layout") :
138 using Teuchos::ParameterList;
143 p.validateParameters(*validParams);
151 template<
typename EvalT,
typename Traits>
164 field_mults_host_mirror(i) =
fieldMults_[i].get_static_view();
172 if (!use_shared_memory) {
173 if (Sacado::IsADType<ScalarT>::value) {
174 const auto fadSize = Sacado::dimension_scalar(
field_.get_view());
175 tmp_ = PHX::View<ScalarT*>(
"GradBasisDotVector::tmp_",
field_.extent(0),fadSize);
177 tmp_ = PHX::View<ScalarT*>(
"GradBasisDotVector::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::ExecutionSpace>::member_type& team)
const
197 const int cell = team.league_rank();
202 const int numQP(
vector_.extent(1)), numSpatialDim(
basis_.extent(3)),
203 numBases(
basis_.extent(1));
207 Kokkos::parallel_for(Kokkos::TeamThreadRange(team,0,numBases), [&] (
const int basis) {
208 field_(cell, basis) = 0.0;
211 for (
int qp(0); qp < numQP; ++qp) {
212 for (
int dim(0); dim < numSpatialDim; ++dim) {
213 if constexpr (NUM_FIELD_MULT == 0) {
214 Kokkos::parallel_for(Kokkos::TeamThreadRange(team,0,numBases), [&] (
const int basis) {
218 else if constexpr (NUM_FIELD_MULT == 1) {
219 Kokkos::parallel_for(Kokkos::TeamThreadRange(team,0,numBases), [&] (
const int basis) {
224 else if constexpr (NUM_FIELD_MULT == 2) {
225 Kokkos::parallel_for(Kokkos::TeamThreadRange(team,0,numBases), [&] (
const int basis) {
230 else if constexpr (NUM_FIELD_MULT == 3) {
231 Kokkos::parallel_for(Kokkos::TeamThreadRange(team,0,numBases), [&] (
const int basis) {
237 Kokkos::abort(
"Panzer_Integrator_GradBasisDotVector: NUM_FIELD_MULT out of range!");
248 template<
typename EvalT,
typename Traits>
249 template<
int NUM_FIELD_MULT>
250 KOKKOS_INLINE_FUNCTION
255 const Kokkos::TeamPolicy<PHX::ExecutionSpace>::member_type& team)
const
258 const int cell = team.league_rank();
259 const int numQP =
vector_.extent(1);
261 const int numSpatialDim =
basis_.extent(3);
262 const int numBases =
basis_.extent(1);
263 const int fadSize = Sacado::dimension_scalar(
field_.get_view());
266 if (Sacado::IsADType<ScalarT>::value) {
267 tmp_field =
scratch_view(team.team_shmem(),numBases,fadSize);
274 Kokkos::parallel_for(Kokkos::TeamThreadRange(team,0,numBases), [&] (
const int basis) {
275 tmp_field(basis) = 0.0;
280 for (
int qp(0); qp < numQP; ++qp) {
281 for (
int dim(0); dim < numSpatialDim; ++dim) {
282 if constexpr (NUM_FIELD_MULT == 0) {
283 Kokkos::parallel_for(Kokkos::TeamThreadRange(team,0,numBases), [&] (
const int basis) {
287 else if constexpr (NUM_FIELD_MULT == 1) {
288 Kokkos::parallel_for(Kokkos::TeamThreadRange(team,0,numBases), [&] (
const int basis) {
293 else if constexpr (NUM_FIELD_MULT == 2) {
294 Kokkos::parallel_for(Kokkos::TeamThreadRange(team,0,numBases), [&] (
const int basis) {
299 else if constexpr (NUM_FIELD_MULT == 3) {
300 Kokkos::parallel_for(Kokkos::TeamThreadRange(team,0,numBases), [&] (
const int basis) {
306 Kokkos::abort(
"Panzer_Integrator_GradBasisDotVector: NUM_FIELD_MULT out of range!");
313 Kokkos::parallel_for(Kokkos::TeamThreadRange(team,0,numBases),[&] (
const int basis) {
314 field_(cell,basis) = tmp_field(basis);
318 Kokkos::parallel_for(Kokkos::TeamThreadRange(team,0,numBases),[&] (
const int basis) {
319 field_(cell,basis) += tmp_field(basis);
330 template<
typename EvalT,
typename Traits>
336 using Kokkos::parallel_for;
337 using Kokkos::TeamPolicy;
343 if (use_shared_memory) {
345 if (Sacado::IsADType<ScalarT>::value) {
346 const int fadSize = Sacado::dimension_scalar(
field_.get_view());
347 bytes = scratch_view::shmem_size(
basis_.extent(1),fadSize);
350 bytes = scratch_view::shmem_size(
basis_.extent(1));
357 parallel_for(this->getName(), policy, *
this);
360 parallel_for(this->getName(), policy, *
this);
363 parallel_for(this->getName(), policy, *
this);
366 parallel_for(this->getName(), policy, *
this);
368 TEUCHOS_TEST_FOR_EXCEPTION(
fieldMults_.size() > 3,std::runtime_error,
369 "ERROR: Panzer_Integrator_GradBasisDotVector supports up to three field multipliers! User requested "
379 parallel_for(this->getName(), policy, *
this);
382 parallel_for(this->getName(), policy, *
this);
385 parallel_for(this->getName(), policy, *
this);
388 parallel_for(this->getName(), policy, *
this);
390 TEUCHOS_TEST_FOR_EXCEPTION(
fieldMults_.size() > 3,std::runtime_error,
391 "ERROR: Panzer_Integrator_GradBasisDotVector supports up to three field multipliers! User requested "
402 template<
typename EvalT,
typename TRAITS>
403 Teuchos::RCP<Teuchos::ParameterList>
409 using PHX::DataLayout;
412 using Teuchos::ParameterList;
417 RCP<ParameterList> p = rcp(
new ParameterList);
418 p->set<
string>(
"Residual Name",
"?");
419 p->set<
string>(
"Flux Name",
"?");
420 RCP<BasisIRLayout> basis;
421 p->set(
"Basis", basis);
422 RCP<IntegrationRule> ir;
424 p->set<
double>(
"Multiplier", 1.0);
425 RCP<const vector<string>> fms;
426 p->set(
"Field Multipliers", fms);
427 RCP<DataLayout> vecDL;
428 p->set(
"Vector Data Layout", vecDL);
Teuchos::RCP< PHX::DataLayout > functional
<Cell,Basis>
Teuchos::RCP< const PureBasis > getBasis() const
WorksetDetailsAccessor wda
static HP & inst()
Private ctor.
bool useSharedMemory() const
Kokkos::TeamPolicy< TeamPolicyProperties... > teamPolicy(const int &league_size)
Returns a TeamPolicy for hierarchic parallelism.
PHX::View< ScalarT * > tmp_
Temporary used when shared memory is disabled.
PHX::MDField< ScalarT, panzer::Cell, panzer::BASIS > field_
A field to which we'll contribute, or in which we'll store, the result of computing this integral.
double multiplier_
The scalar multiplier out in front of the integral ( ).
Teuchos::RCP< Teuchos::ParameterList > getValidParameters() const
Get Valid Parameters.
std::vector< PHX::MDField< const ScalarT, panzer::Cell, panzer::IP > > fieldMults_
The (possibly empty) list of fields that are multipliers out in front of the integral ( ,...
Integrator_GradBasisDotVector(const panzer::EvaluatorStyle &evalStyle, const std::string &resName, const std::string &fluxName, const panzer::BasisIRLayout &basis, const panzer::IntegrationRule &ir, const double &multiplier=1, const std::vector< std::string > &fmNames=std::vector< std::string >(), const Teuchos::RCP< PHX::DataLayout > &vecDL=Teuchos::null)
Main Constructor.
typename EvalT::ScalarT ScalarT
The scalar type.
Kokkos::View< ScalarT *,typename PHX::DevLayout< ScalarT >::type, typename PHX::ExecutionSpace::scratch_memory_space, Kokkos::MemoryUnmanaged > scratch_view
Type for shared memory.
void postRegistrationSetup(typename Traits::SetupData d, PHX::FieldManager< Traits > &fm)
Post-Registration Setup.
PHX::MDField< const ScalarT, panzer::Cell, panzer::IP, panzer::Dim > vector_
A field representing the vector-valued function we're integrating ( ).
const panzer::EvaluatorStyle evalStyle_
An enum determining the behavior of this Evaluator.
std::string basisName_
The name of the basis we're using.
PHX::View< PHX::UnmanagedView< const ScalarT ** > * > kokkosFieldMults_
The PHX::View representation of the (possibly empty) list of fields that are multipliers out in front...
PHX::MDField< double, panzer::Cell, panzer::BASIS, panzer::IP, panzer::Dim > basis_
The gradient vector basis information necessary for integration.
KOKKOS_INLINE_FUNCTION void operator()(const FieldMultTag< NUM_FIELD_MULT > &tag, const Kokkos::TeamPolicy< PHX::ExecutionSpace >::member_type &team) const
Perform the integration.
void evaluateFields(typename Traits::EvalData d)
Evaluate Fields.
std::size_t basisIndex_
The index in the Workset bases for our particular BasisIRLayout name.
Teuchos::RCP< PHX::DataLayout > dl_vector
Data layout for vector fields.
Teuchos::RCP< PHX::DataLayout > dl_scalar
Data layout for scalar fields.
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....
Teuchos::RCP< const std::vector< panzer::Workset > > worksets_
All worksets that will be evaluated over the lifetime of this evaluator.
const panzer::Workset & EvalData
Data type passed to PHX::Evaluator::evaluateFields(): a single workset holding the cell data for one ...
const SD & SetupData
Data type passed to PHX::Evaluator::postRegistrationSetup().