Panzer  Version of the Day
Panzer_GatherSolution_Tpetra_impl.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Panzer: A partial differential equation assembly
5 // engine for strongly coupled complex multiphysics systems
6 // Copyright (2011) Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact Roger P. Pawlowski (rppawlo@sandia.gov) and
39 // Eric C. Cyr (eccyr@sandia.gov)
40 // ***********************************************************************
41 // @HEADER
42 
43 #ifndef PANZER_GATHER_SOLUTION_TPETRA_IMPL_HPP
44 #define PANZER_GATHER_SOLUTION_TPETRA_IMPL_HPP
45 
46 #include "Teuchos_Assert.hpp"
47 #include "Phalanx_DataLayout.hpp"
48 
50 #include "Panzer_PureBasis.hpp"
55 
56 #include "Teuchos_FancyOStream.hpp"
57 
58 #include "Tpetra_Vector.hpp"
59 #include "Tpetra_Map.hpp"
60 
61 // **********************************************************************
62 // Specialization: Residual
63 // **********************************************************************
64 
65 template<typename TRAITS,typename LO,typename GO,typename NodeT>
68  const Teuchos::RCP<const panzer::UniqueGlobalIndexer<LO,GO> > & indexer,
69  const Teuchos::ParameterList& p)
70  : globalIndexer_(indexer)
71  , has_tangent_fields_(false)
72 {
73  typedef std::vector< std::vector<std::string> > vvstring;
74 
76  input.setParameterList(p);
77 
78  const std::vector<std::string> & names = input.getDofNames();
80  const vvstring & tangent_field_names = input.getTangentNames();
81 
82  indexerNames_ = input.getIndexerNames();
83  useTimeDerivativeSolutionVector_ = input.useTimeDerivativeSolutionVector();
84  globalDataKey_ = input.getGlobalDataKey();
85 
86  // allocate fields
87  gatherFields_.resize(names.size());
88  for (std::size_t fd = 0; fd < names.size(); ++fd) {
89  gatherFields_[fd] =
90  PHX::MDField<ScalarT,Cell,NODE>(names[fd],basis->functional);
91  this->addEvaluatedField(gatherFields_[fd]);
92  }
93 
94  // Setup dependent tangent fields if requested
95  if (tangent_field_names.size()>0) {
96  TEUCHOS_ASSERT(gatherFields_.size() == tangent_field_names.size());
97 
98  has_tangent_fields_ = true;
99  tangentFields_.resize(gatherFields_.size());
100  for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) {
101  tangentFields_[fd].resize(tangent_field_names[fd].size());
102  for (std::size_t i=0; i<tangent_field_names[fd].size(); ++i) {
103  tangentFields_[fd][i] =
104  PHX::MDField<const ScalarT,Cell,NODE>(tangent_field_names[fd][i],basis->functional);
105  this->addDependentField(tangentFields_[fd][i]);
106  }
107  }
108  }
109 
110  // figure out what the first active name is
111  std::string firstName = "<none>";
112  if(names.size()>0)
113  firstName = names[0];
114 
115  std::string n = "GatherSolution (Tpetra): "+firstName+" (Residual)";
116  this->setName(n);
117 }
118 
119 // **********************************************************************
120 template<typename TRAITS,typename LO,typename GO,typename NodeT>
122 postRegistrationSetup(typename TRAITS::SetupData d,
124 {
125  TEUCHOS_ASSERT(gatherFields_.size() == indexerNames_.size());
126 
127  fieldIds_.resize(gatherFields_.size());
128 
129  for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) {
130  const std::string& fieldName = indexerNames_[fd];
131  fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
132 
133  // setup the field data object
134  this->utils.setFieldData(gatherFields_[fd],fm);
135  }
136 
137  if (has_tangent_fields_) {
138  for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd)
139  for (std::size_t i=0; i<tangentFields_[fd].size(); ++i)
140  this->utils.setFieldData(tangentFields_[fd][i],fm);
141  }
142 
143  indexerNames_.clear(); // Don't need this anymore
144 }
145 
146 // **********************************************************************
147 template<typename TRAITS,typename LO,typename GO,typename NodeT>
149 preEvaluate(typename TRAITS::PreEvalData d)
150 {
152 
153  // extract linear object container
154  tpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(d.gedc.getDataObject(globalDataKey_));
155 
156  if(tpetraContainer_==Teuchos::null) {
157  // extract linear object container
158  Teuchos::RCP<LinearObjContainer> loc = Teuchos::rcp_dynamic_cast<LOCPair_GlobalEvaluationData>(d.gedc.getDataObject(globalDataKey_),true)->getGhostedLOC();
159  tpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(loc);
160  }
161 }
162 
163 // **********************************************************************
164 template<typename TRAITS,typename LO,typename GO,typename NodeT>
166 evaluateFields(typename TRAITS::EvalData workset)
167 {
169 
170  std::vector<LO> LIDs;
171 
172  // for convenience pull out some objects from workset
173  std::string blockId = this->wda(workset).block_id;
174  const std::vector<std::size_t> & localCellIds = this->wda(workset).cell_local_ids;
175 
177  if (useTimeDerivativeSolutionVector_)
178  x = tpetraContainer_->get_dxdt();
179  else
180  x = tpetraContainer_->get_x();
181 
182  Teuchos::ArrayRCP<const double> x_array = x->get1dView();
183 
184  // NOTE: A reordering of these loops will likely improve performance
185  // The "getGIDFieldOffsets may be expensive. However the
186  // "getElementGIDs" can be cheaper. However the lookup for LIDs
187  // may be more expensive!
188 
189  // gather operation for each cell in workset
190  for(std::size_t worksetCellIndex=0;worksetCellIndex<localCellIds.size();++worksetCellIndex) {
191  std::size_t cellLocalId = localCellIds[worksetCellIndex];
192 
193  LIDs = globalIndexer_->getElementLIDs(cellLocalId);
194 
195  // loop over the fields to be gathered
196  for (std::size_t fieldIndex=0; fieldIndex<gatherFields_.size();fieldIndex++) {
197  int fieldNum = fieldIds_[fieldIndex];
198  const std::vector<int> & elmtOffset = globalIndexer_->getGIDFieldOffsets(blockId,fieldNum);
199 
200  // loop over basis functions and fill the fields
201  for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
202  int offset = elmtOffset[basis];
203  LO lid = LIDs[offset];
204  (gatherFields_[fieldIndex])(worksetCellIndex,basis) = x_array[lid];
205  }
206  }
207  }
208 }
209 
210 // **********************************************************************
211 // Specialization: Tangent
212 // **********************************************************************
213 
214 template<typename TRAITS,typename LO,typename GO,typename NodeT>
217  const Teuchos::RCP<const panzer::UniqueGlobalIndexer<LO,GO> > & indexer,
218  const Teuchos::ParameterList& p)
219  : globalIndexer_(indexer)
220  , has_tangent_fields_(false)
221 {
222  typedef std::vector< std::vector<std::string> > vvstring;
223 
225  input.setParameterList(p);
226 
227  const std::vector<std::string> & names = input.getDofNames();
229  const vvstring & tangent_field_names = input.getTangentNames();
230 
231  indexerNames_ = input.getIndexerNames();
232  useTimeDerivativeSolutionVector_ = input.useTimeDerivativeSolutionVector();
233  globalDataKey_ = input.getGlobalDataKey();
234 
235  // allocate fields
236  gatherFields_.resize(names.size());
237  for (std::size_t fd = 0; fd < names.size(); ++fd) {
238  gatherFields_[fd] =
239  PHX::MDField<ScalarT,Cell,NODE>(names[fd],basis->functional);
240  this->addEvaluatedField(gatherFields_[fd]);
241  }
242 
243  // Setup dependent tangent fields if requested
244  if (tangent_field_names.size()>0) {
245  TEUCHOS_ASSERT(gatherFields_.size() == tangent_field_names.size());
246 
247  has_tangent_fields_ = true;
248  tangentFields_.resize(gatherFields_.size());
249  for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) {
250  tangentFields_[fd].resize(tangent_field_names[fd].size());
251  for (std::size_t i=0; i<tangent_field_names[fd].size(); ++i) {
252  tangentFields_[fd][i] =
253  PHX::MDField<const RealT,Cell,NODE>(tangent_field_names[fd][i],basis->functional);
254  this->addDependentField(tangentFields_[fd][i]);
255  }
256  }
257  }
258 
259  // figure out what the first active name is
260  std::string firstName = "<none>";
261  if(names.size()>0)
262  firstName = names[0];
263 
264  std::string n = "GatherSolution (Tpetra): "+firstName+" (Tangent)";
265  this->setName(n);
266 }
267 
268 // **********************************************************************
269 template<typename TRAITS,typename LO,typename GO,typename NodeT>
271 postRegistrationSetup(typename TRAITS::SetupData d,
273 {
274  TEUCHOS_ASSERT(gatherFields_.size() == indexerNames_.size());
275 
276  fieldIds_.resize(gatherFields_.size());
277 
278  for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) {
279  const std::string& fieldName = indexerNames_[fd];
280  fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
281 
282  // setup the field data object
283  this->utils.setFieldData(gatherFields_[fd],fm);
284  }
285 
286  if (has_tangent_fields_) {
287  for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd)
288  for (std::size_t i=0; i<tangentFields_[fd].size(); ++i)
289  this->utils.setFieldData(tangentFields_[fd][i],fm);
290  }
291 
292  indexerNames_.clear(); // Don't need this anymore
293 }
294 
295 // **********************************************************************
296 template<typename TRAITS,typename LO,typename GO,typename NodeT>
298 preEvaluate(typename TRAITS::PreEvalData d)
299 {
301 
302  // extract linear object container
303  tpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(d.gedc.getDataObject(globalDataKey_));
304 
305  if(tpetraContainer_==Teuchos::null) {
306  // extract linear object container
307  Teuchos::RCP<LinearObjContainer> loc = Teuchos::rcp_dynamic_cast<LOCPair_GlobalEvaluationData>(d.gedc.getDataObject(globalDataKey_),true)->getGhostedLOC();
308  tpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(loc);
309  }
310 }
311 
312 // **********************************************************************
313 template<typename TRAITS,typename LO,typename GO,typename NodeT>
315 evaluateFields(typename TRAITS::EvalData workset)
316 {
318 
319  std::vector<LO> LIDs;
320 
321  // for convenience pull out some objects from workset
322  std::string blockId = this->wda(workset).block_id;
323  const std::vector<std::size_t> & localCellIds = this->wda(workset).cell_local_ids;
324 
326  if (useTimeDerivativeSolutionVector_)
327  x = tpetraContainer_->get_dxdt();
328  else
329  x = tpetraContainer_->get_x();
330 
331  Teuchos::ArrayRCP<const double> x_array = x->get1dView();
332 
333  // NOTE: A reordering of these loops will likely improve performance
334  // The "getGIDFieldOffsets may be expensive. However the
335  // "getElementGIDs" can be cheaper. However the lookup for LIDs
336  // may be more expensive!
337 
338  typedef typename PHX::MDField<ScalarT,Cell,NODE>::array_type::reference_type reference_type;
339 
340  if (has_tangent_fields_) {
341  // gather operation for each cell in workset
342  for(std::size_t worksetCellIndex=0;worksetCellIndex<localCellIds.size();++worksetCellIndex) {
343  std::size_t cellLocalId = localCellIds[worksetCellIndex];
344 
345  LIDs = globalIndexer_->getElementLIDs(cellLocalId);
346 
347  // loop over the fields to be gathered
348  for (std::size_t fieldIndex=0; fieldIndex<gatherFields_.size();fieldIndex++) {
349  int fieldNum = fieldIds_[fieldIndex];
350  const std::vector<int> & elmtOffset = globalIndexer_->getGIDFieldOffsets(blockId,fieldNum);
351 
352  const std::vector< PHX::MDField<const RealT,Cell,NODE> >& tf_ref =
353  tangentFields_[fieldIndex];
354  const std::size_t num_tf = tf_ref.size();
355 
356  // loop over basis functions and fill the fields
357  for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
358  int offset = elmtOffset[basis];
359  LO lid = LIDs[offset];
360  reference_type gf_ref = (gatherFields_[fieldIndex])(worksetCellIndex,basis);
361  gf_ref.val() = x_array[lid];
362  for (std::size_t i=0; i<num_tf; ++i)
363  gf_ref.fastAccessDx(i) = tf_ref[i](worksetCellIndex,basis);
364  }
365  }
366  }
367  }
368  else {
369  // gather operation for each cell in workset
370  for(std::size_t worksetCellIndex=0;worksetCellIndex<localCellIds.size();++worksetCellIndex) {
371  std::size_t cellLocalId = localCellIds[worksetCellIndex];
372 
373  LIDs = globalIndexer_->getElementLIDs(cellLocalId);
374 
375  // loop over the fields to be gathered
376  for (std::size_t fieldIndex=0; fieldIndex<gatherFields_.size();fieldIndex++) {
377  int fieldNum = fieldIds_[fieldIndex];
378  const std::vector<int> & elmtOffset = globalIndexer_->getGIDFieldOffsets(blockId,fieldNum);
379 
380  // loop over basis functions and fill the fields
381  for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
382  int offset = elmtOffset[basis];
383  LO lid = LIDs[offset];
384  reference_type gf_ref = (gatherFields_[fieldIndex])(worksetCellIndex,basis);
385  gf_ref.val() = x_array[lid];
386  }
387  }
388  }
389  }
390 }
391 
392 // **********************************************************************
393 // Specialization: Jacobian
394 // **********************************************************************
395 
396 template<typename TRAITS,typename LO,typename GO,typename NodeT>
399  const Teuchos::RCP<const panzer::UniqueGlobalIndexer<LO,GO> > & indexer,
400  const Teuchos::ParameterList& p)
401  : globalIndexer_(indexer)
402 {
403  // typedef std::vector< std::vector<std::string> > vvstring;
404 
406  input.setParameterList(p);
407 
408  const std::vector<std::string> & names = input.getDofNames();
410  //const vvstring & tangent_field_names = input.getTangentNames();
411 
412  indexerNames_ = input.getIndexerNames();
413  useTimeDerivativeSolutionVector_ = input.useTimeDerivativeSolutionVector();
414  globalDataKey_ = input.getGlobalDataKey();
415 
416  gatherSeedIndex_ = input.getGatherSeedIndex();
417  sensitivitiesName_ = input.getSensitivitiesName();
418  disableSensitivities_ = !input.firstSensitivitiesAvailable();
419 
420  gatherFields_.resize(names.size());
421  scratch_offsets_.resize(names.size());
422  for (std::size_t fd = 0; fd < names.size(); ++fd) {
423  PHX::MDField<ScalarT,Cell,NODE> f(names[fd],basis->functional);
424  gatherFields_[fd] = f;
425  this->addEvaluatedField(gatherFields_[fd]);
426  }
427 
428  // figure out what the first active name is
429  std::string firstName = "<none>";
430  if(names.size()>0)
431  firstName = names[0];
432 
433  // print out convenience
434  if(disableSensitivities_) {
435  std::string n = "GatherSolution (Tpetra, No Sensitivities): "+firstName+" (Jacobian)";
436  this->setName(n);
437  }
438  else {
439  std::string n = "GatherSolution (Tpetra): "+firstName+" ("+PHX::typeAsString<EvalT>()+") ";
440  this->setName(n);
441  }
442 }
443 
444 // **********************************************************************
445 template<typename TRAITS,typename LO,typename GO,typename NodeT>
447 postRegistrationSetup(typename TRAITS::SetupData d,
449 {
450  TEUCHOS_ASSERT(gatherFields_.size() == indexerNames_.size());
451 
452  fieldIds_.resize(gatherFields_.size());
453 
454  const Workset & workset_0 = (*d.worksets_)[0];
455  std::string blockId = this->wda(workset_0).block_id;
456 
457  for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) {
458  // get field ID from DOF manager
459  const std::string& fieldName = indexerNames_[fd];
460  fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
461 
462  // setup the field data object
463  this->utils.setFieldData(gatherFields_[fd],fm);
464 
465  int fieldNum = fieldIds_[fd];
466  const std::vector<int> & offsets = globalIndexer_->getGIDFieldOffsets(blockId,fieldNum);
467  scratch_offsets_[fd] = Kokkos::View<int*,PHX::Device>("offsets",offsets.size());
468  for(std::size_t i=0;i<offsets.size();i++)
469  scratch_offsets_[fd](i) = offsets[i];
470  }
471 
472  scratch_lids_ = Kokkos::View<LO**,PHX::Device>("lids",gatherFields_[0].dimension_0(),
473  globalIndexer_->getElementBlockGIDCount(blockId));
474 
475  indexerNames_.clear(); // Don't need this anymore
476 }
477 
478 // **********************************************************************
479 template<typename TRAITS,typename LO,typename GO,typename NodeT>
481 preEvaluate(typename TRAITS::PreEvalData d)
482 {
483  using Teuchos::RCP;
484  using Teuchos::rcp;
485  using Teuchos::rcp_dynamic_cast;
486 
489 
490  // manage sensitivities
492  if(!disableSensitivities_) {
493  if(d.first_sensitivities_name==sensitivitiesName_)
494  applySensitivities_ = true;
495  else
496  applySensitivities_ = false;
497  }
498  else
499  applySensitivities_ = false;
500 
502 
504 
505  // first try refactored ReadOnly container
506  std::string post = useTimeDerivativeSolutionVector_ ? " - Xdot" : " - X";
507  if(d.gedc.containsDataObject(globalDataKey_+post)) {
508  ged = d.gedc.getDataObject(globalDataKey_+post);
509 
510  RCP<RO_GED> ro_ged = rcp_dynamic_cast<RO_GED>(ged,true);
511 
512  x_vector = ro_ged->getGhostedVector_Tpetra();
513 
514  x_vector->template sync<PHX::Device>();
515 
516  return;
517  }
518 
519  ged = d.gedc.getDataObject(globalDataKey_);
520 
521  // try to extract linear object container
522  {
523  RCP<LOC> tpetraContainer = rcp_dynamic_cast<LOC>(ged);
524  RCP<LOCPair_GlobalEvaluationData> loc_pair = rcp_dynamic_cast<LOCPair_GlobalEvaluationData>(ged);
525 
526  if(loc_pair!=Teuchos::null) {
527  Teuchos::RCP<LinearObjContainer> loc = loc_pair->getGhostedLOC();
528  // extract linear object container
529  tpetraContainer = rcp_dynamic_cast<LOC>(loc);
530  }
531 
532  if(tpetraContainer!=Teuchos::null) {
533  if (useTimeDerivativeSolutionVector_)
534  x_vector = tpetraContainer->get_dxdt();
535  else
536  x_vector = tpetraContainer->get_x();
537 
538  x_vector->template sync<PHX::Device>();
539 
540  return; // epetraContainer was found
541  }
542  }
543 
544  // try to extract an EpetraVector_ReadOnly object (this is the last resort!, it throws if not found)
545  {
546  RCP<RO_GED> ro_ged = rcp_dynamic_cast<RO_GED>(ged,true);
547 
548  x_vector = ro_ged->getGhostedVector_Tpetra();
549  }
550 
551  x_vector->template sync<PHX::Device>();
552 }
553 
554 // **********************************************************************
555 template<typename TRAITS,typename LO,typename GO,typename NodeT>
557 evaluateFields(typename TRAITS::EvalData workset)
558 {
559  // for convenience pull out some objects from workset
560  std::string blockId = this->wda(workset).block_id;
561 
562  double seed_value = 0.0;
563  if (useTimeDerivativeSolutionVector_) {
564  seed_value = workset.alpha;
565  }
566  else if (gatherSeedIndex_<0) {
567  seed_value = workset.beta;
568  }
569  else if(!useTimeDerivativeSolutionVector_) {
570  seed_value = workset.gather_seeds[gatherSeedIndex_];
571  }
572  else {
573  TEUCHOS_ASSERT(false);
574  }
575 
576  // turn off sensitivies: this may be faster if we don't expand the term
577  // but I suspect not because anywhere it is used the full complement of
578  // sensitivies will be needed anyway.
579  if(!applySensitivities_)
580  seed_value = 0.0;
581 
582  // switch to a faster assembly
583  bool use_seed = true;
584  if(seed_value==0.0)
585  use_seed = false;
586 
587  globalIndexer_->getElementLIDs(this->wda(workset).cell_local_ids_k,scratch_lids_);
588 
589  // now setup the fuctor_data, and run the parallel_for loop
591 
592  functor_data.x_data = x_vector->template getLocalView<PHX::Device>();
593  functor_data.seed_value = seed_value;
594  functor_data.lids = scratch_lids_;
595 
596  // loop over the fields to be gathered
597  for(std::size_t fieldIndex=0;
598  fieldIndex<gatherFields_.size();fieldIndex++) {
599 
600  // setup functor data
601  functor_data.offsets = scratch_offsets_[fieldIndex];
602  functor_data.field = gatherFields_[fieldIndex];
603 
604  if(use_seed)
605  Kokkos::parallel_for(workset.num_cells,*this);
606  else
607  Kokkos::parallel_for(Kokkos::RangePolicy<PHX::Device,NoSeed>(0,workset.num_cells),*this);
608  }
609 }
610 
611 // **********************************************************************
612 template<typename TRAITS,typename LO,typename GO,typename NodeT>
613 KOKKOS_INLINE_FUNCTION
615 operator()(const int worksetCellIndex) const
616 {
617  // loop over basis functions and fill the fields
618  for(std::size_t basis=0;basis<functor_data.offsets.dimension_0();basis++) {
619  int offset = functor_data.offsets(basis);
620  LO lid = functor_data.lids(worksetCellIndex,offset);
621 
622  // set the value and seed the FAD object
623  functor_data.field(worksetCellIndex,basis).val() = functor_data.x_data(lid,0);
624  functor_data.field(worksetCellIndex,basis).fastAccessDx(offset) = functor_data.seed_value;
625  }
626 }
627 
628 // **********************************************************************
629 template<typename TRAITS,typename LO,typename GO,typename NodeT>
630 KOKKOS_INLINE_FUNCTION
632 operator()(const NoSeed,const int worksetCellIndex) const
633 {
634  // loop over basis functions and fill the fields
635  for(std::size_t basis=0;basis<functor_data.offsets.dimension_0();basis++) {
636  int offset = functor_data.offsets(basis);
637  LO lid = functor_data.lids(worksetCellIndex,offset);
638 
639  // set the value and seed the FAD object
640  functor_data.field(worksetCellIndex,basis).val() = functor_data.x_data(lid,0);
641  }
642 }
643 
644 // **********************************************************************
645 
646 #endif
PHX::MDField< const ScalarT > input
void operator()(const FieldMultTag< NUM_FIELD_MULT > &, const std::size_t &cell) const
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Gathers solution values from the Newton solution vector into the nodal fields of the field manager...
Teuchos::RCP< const panzer::PureBasis > basis
Interpolates basis DOF values to IP DOF values.
#define TEUCHOS_ASSERT(assertion_test)
Teuchos::RCP< PHX::DataLayout > functional
<Cell,Basis> or <Cell,Basis>
Kokkos::View< const int *, PHX::Device > offsets