Panzer Version of the Day
Loading...
Searching...
No Matches
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
25
26namespace 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,
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;
72 TEUCHOS_TEST_FOR_EXCEPTION(
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 :
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 {
125 using Teuchos::ParameterList;
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,
144 {
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>
319 Teuchos::RCP<Teuchos::ParameterList>
322 {
325 using PHX::DataLayout;
326 using std::string;
327 using std::vector;
328 using Teuchos::ParameterList;
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);
338 RCP<IntegrationRule> ir;
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__
panzer::EvaluatorStyle evalStyle
The EvaluatorStyle of the parent Integrator_CurlBasisDotVector object.
Teuchos::RCP< PHX::DataLayout > functional
<Cell,Basis>
Teuchos::RCP< const PureBasis > getBasis() const
static HP & inst()
Private ctor.
Kokkos::TeamPolicy< TeamPolicyProperties... > teamPolicy(const int &league_size)
Returns a TeamPolicy for hierarchic parallelism.
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.
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.
KOKKOS_INLINE_FUNCTION void operator()(const FieldMultTag &tag, const Kokkos::TeamPolicy< PHX::exec_space >::member_type &team) const
Perform the integration.
Teuchos::RCP< Teuchos::ParameterList > getValidParameters() const
Get Valid Parameters.
Kokkos::View< ScalarT *,typename PHX::DevLayout< ScalarT >::type, typename PHX::exec_space::scratch_memory_space, Kokkos::MemoryUnmanaged > scratch_view
Type for shared memory.
PHX::MDField< const ScalarT, panzer::Cell, panzer::IP, panzer::Dim, panzer::Dim > tensor_
The tensor field( ).
PHX::MDField< const ScalarT, panzer::Cell, panzer::IP, panzer::Dim > vector_
A field representing the vector-valued function we're integrating ( ).
void postRegistrationSetup(typename Traits::SetupData d, PHX::FieldManager< Traits > &fm)
Post-Registration Setup.
const panzer::EvaluatorStyle evalStyle_
An enum determining the behavior of this Evaluator.
Teuchos::RCP< PHX::DataLayout > dl_vector
Data layout for vector fields.
Teuchos::RCP< PHX::DataLayout > dl_tensor
Data layout for rank-2 tensor 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_