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 
49 #include "Panzer_GlobalIndexer.hpp"
50 #include "Panzer_PureBasis.hpp"
56 
57 #include "Teuchos_FancyOStream.hpp"
58 
59 #include "Tpetra_Vector.hpp"
60 #include "Tpetra_Map.hpp"
61 
62 // **********************************************************************
63 // Specialization: Residual
64 // **********************************************************************
65 
66 template<typename TRAITS,typename LO,typename GO,typename NodeT>
69  const Teuchos::RCP<const panzer::GlobalIndexer> & indexer,
70  const Teuchos::ParameterList& p)
71  : globalIndexer_(indexer)
72  , has_tangent_fields_(false)
73 {
74  typedef std::vector< std::vector<std::string> > vvstring;
75 
77  input.setParameterList(p);
78 
79  const std::vector<std::string> & names = input.getDofNames();
80  Teuchos::RCP<const panzer::PureBasis> basis = input.getBasis();
81  const vvstring & tangent_field_names = input.getTangentNames();
82 
83  indexerNames_ = input.getIndexerNames();
84  useTimeDerivativeSolutionVector_ = input.useTimeDerivativeSolutionVector();
85  globalDataKey_ = input.getGlobalDataKey();
86 
87  // allocate fields
88  gatherFields_.resize(names.size());
89  for (std::size_t fd = 0; fd < names.size(); ++fd) {
90  gatherFields_[fd] =
91  PHX::MDField<ScalarT,Cell,NODE>(names[fd],basis->functional);
92  this->addEvaluatedField(gatherFields_[fd]);
93  }
94 
95  // Setup dependent tangent fields if requested
96  if (tangent_field_names.size()>0) {
97  TEUCHOS_ASSERT(gatherFields_.size() == tangent_field_names.size());
98 
99  has_tangent_fields_ = true;
100  tangentFields_.resize(gatherFields_.size());
101  for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) {
102  tangentFields_[fd].resize(tangent_field_names[fd].size());
103  for (std::size_t i=0; i<tangent_field_names[fd].size(); ++i) {
104  tangentFields_[fd][i] =
105  PHX::MDField<const ScalarT,Cell,NODE>(tangent_field_names[fd][i],basis->functional);
106  this->addDependentField(tangentFields_[fd][i]);
107  }
108  }
109  }
110 
111  // figure out what the first active name is
112  std::string firstName = "<none>";
113  if(names.size()>0)
114  firstName = names[0];
115 
116  std::string n = "GatherSolution (Tpetra): "+firstName+" (Residual)";
117  this->setName(n);
118 }
119 
120 // **********************************************************************
121 template<typename TRAITS,typename LO,typename GO,typename NodeT>
123 postRegistrationSetup(typename TRAITS::SetupData d,
124  PHX::FieldManager<TRAITS>& /* fm */)
125 {
126  TEUCHOS_ASSERT(gatherFields_.size() == indexerNames_.size());
127 
128  fieldIds_.resize(gatherFields_.size());
129 
130  const Workset & workset_0 = (*d.worksets_)[0];
131  std::string blockId = this->wda(workset_0).block_id;
132  scratch_offsets_.resize(gatherFields_.size());
133 
134  for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) {
135  const std::string& fieldName = indexerNames_[fd];
136  fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
137 
138  int fieldNum = fieldIds_[fd];
139  const std::vector<int> & offsets = globalIndexer_->getGIDFieldOffsets(blockId,fieldNum);
140  scratch_offsets_[fd] = PHX::View<int*>("offsets",offsets.size());
141  Kokkos::deep_copy(scratch_offsets_[fd], Kokkos::View<const int*, Kokkos::HostSpace, Kokkos::MemoryUnmanaged>(offsets.data(), offsets.size()));
142  }
143 
144  scratch_lids_ = PHX::View<LO**>("lids",gatherFields_[0].extent(0),
145  globalIndexer_->getElementBlockGIDCount(blockId));
146 
147  indexerNames_.clear(); // Don't need this anymore
148 }
149 
150 // **********************************************************************
151 template<typename TRAITS,typename LO,typename GO,typename NodeT>
153 preEvaluate(typename TRAITS::PreEvalData d)
154 {
156 
157  // extract linear object container
158  tpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(d.gedc->getDataObject(globalDataKey_));
159 
160  if(tpetraContainer_==Teuchos::null) {
161  // extract linear object container
162  Teuchos::RCP<LinearObjContainer> loc = Teuchos::rcp_dynamic_cast<LOCPair_GlobalEvaluationData>(d.gedc->getDataObject(globalDataKey_),true)->getGhostedLOC();
163  tpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(loc);
164  }
165 }
166 
167 // **********************************************************************
168 template<typename TRAITS,typename LO,typename GO,typename NodeT>
170 evaluateFields(typename TRAITS::EvalData workset)
171 {
173 
174  // for convenience pull out some objects from workset
175  std::string blockId = this->wda(workset).block_id;
176  const std::vector<std::size_t> & localCellIds = this->wda(workset).cell_local_ids;
177 
178  Teuchos::RCP<typename LOC::VectorType> x;
179  if (useTimeDerivativeSolutionVector_)
180  x = tpetraContainer_->get_dxdt();
181  else
182  x = tpetraContainer_->get_x();
183 
184  auto x_data = x->getLocalViewDevice(Tpetra::Access::ReadOnly);
185 
186  globalIndexer_->getElementLIDs(this->wda(workset).cell_local_ids_k,scratch_lids_);
187 
188  // NOTE: A reordering of these loops will likely improve performance
189  // The "getGIDFieldOffsets may be expensive. However the
190  // "getElementGIDs" can be cheaper. However the lookup for LIDs
191  // may be more expensive!
192 
193  // gather operation for each cell in workset
194 
195  auto lids = scratch_lids_;
196  for (std::size_t fieldIndex=0; fieldIndex<gatherFields_.size();fieldIndex++) {
197  auto offsets = scratch_offsets_[fieldIndex];
198  auto gather_field = gatherFields_[fieldIndex];
199 
200  Kokkos::parallel_for(localCellIds.size(), KOKKOS_LAMBDA (std::size_t worksetCellIndex) {
201  // loop over basis functions and fill the fields
202  for(std::size_t basis=0;basis<offsets.extent(0);basis++) {
203  int offset = offsets(basis);
204  LO lid = lids(worksetCellIndex,offset);
205 
206  // set the value and seed the FAD object
207  gather_field(worksetCellIndex,basis) = x_data(lid,0);
208  }
209  });
210  }
211 }
212 
213 // **********************************************************************
214 // Specialization: Tangent
215 // **********************************************************************
216 
217 template<typename TRAITS,typename LO,typename GO,typename NodeT>
220  const Teuchos::RCP<const panzer::GlobalIndexer> & indexer,
221  const Teuchos::ParameterList& p)
222  : globalIndexer_(indexer)
223  , has_tangent_fields_(false)
224 {
225  typedef std::vector< std::vector<std::string> > vvstring;
226 
227  GatherSolution_Input input;
228  input.setParameterList(p);
229 
230  const std::vector<std::string> & names = input.getDofNames();
231  Teuchos::RCP<const panzer::PureBasis> basis = input.getBasis();
232  const vvstring & tangent_field_names = input.getTangentNames();
233 
234  indexerNames_ = input.getIndexerNames();
235  useTimeDerivativeSolutionVector_ = input.useTimeDerivativeSolutionVector();
236  globalDataKey_ = input.getGlobalDataKey();
237 
238  // allocate fields
239  gatherFields_.resize(names.size());
240  for (std::size_t fd = 0; fd < names.size(); ++fd) {
241  gatherFields_[fd] =
242  PHX::MDField<ScalarT,Cell,NODE>(names[fd],basis->functional);
243  this->addEvaluatedField(gatherFields_[fd]);
244  // Don't allow for sharing so that we can avoid zeroing out the
245  // off-diagonal values of the FAD derivative array.
246  this->addUnsharedField(gatherFields_[fd].fieldTag().clone());
247  }
248 
249  // Setup dependent tangent fields if requested
250  if (tangent_field_names.size()>0) {
251  TEUCHOS_ASSERT(gatherFields_.size() == tangent_field_names.size());
252 
253  has_tangent_fields_ = true;
254  tangentFields_.resize(gatherFields_.size());
255  for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) {
256  tangentFields_[fd].resize(tangent_field_names[fd].size());
257  for (std::size_t i=0; i<tangent_field_names[fd].size(); ++i) {
258  tangentFields_[fd][i] =
259  PHX::MDField<const RealT,Cell,NODE>(tangent_field_names[fd][i],basis->functional);
260  this->addDependentField(tangentFields_[fd][i]);
261  }
262  }
263  }
264 
265  // figure out what the first active name is
266  std::string firstName = "<none>";
267  if(names.size()>0)
268  firstName = names[0];
269 
270  std::string n = "GatherSolution (Tpetra): "+firstName+" (Tangent)";
271  this->setName(n);
272 }
273 
274 // **********************************************************************
275 template<typename TRAITS,typename LO,typename GO,typename NodeT>
277 postRegistrationSetup(typename TRAITS::SetupData /* d */,
278  PHX::FieldManager<TRAITS>& /* fm */)
279 {
280  TEUCHOS_ASSERT(gatherFields_.size() == indexerNames_.size());
281 
282  fieldIds_.resize(gatherFields_.size());
283 
284  for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) {
285  const std::string& fieldName = indexerNames_[fd];
286  fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
287  }
288 
289  indexerNames_.clear(); // Don't need this anymore
290 }
291 
292 // **********************************************************************
293 template<typename TRAITS,typename LO,typename GO,typename NodeT>
295 preEvaluate(typename TRAITS::PreEvalData d)
296 {
298 
299  // extract linear object container
300  tpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(d.gedc->getDataObject(globalDataKey_));
301 
302  if(tpetraContainer_==Teuchos::null) {
303  // extract linear object container
304  Teuchos::RCP<LinearObjContainer> loc = Teuchos::rcp_dynamic_cast<LOCPair_GlobalEvaluationData>(d.gedc->getDataObject(globalDataKey_),true)->getGhostedLOC();
305  tpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(loc);
306  }
307 }
308 
309 // **********************************************************************
310 template<typename TRAITS,typename LO,typename GO,typename NodeT>
312 evaluateFields(typename TRAITS::EvalData workset)
313 {
315 
316  // for convenience pull out some objects from workset
317  std::string blockId = this->wda(workset).block_id;
318  const std::vector<std::size_t> & localCellIds = this->wda(workset).cell_local_ids;
319 
320  Teuchos::RCP<typename LOC::VectorType> x;
321  if (useTimeDerivativeSolutionVector_)
322  x = tpetraContainer_->get_dxdt();
323  else
324  x = tpetraContainer_->get_x();
325 
326  Teuchos::ArrayRCP<const double> x_array = x->get1dView();
327 
328  // NOTE: A reordering of these loops will likely improve performance
329  // The "getGIDFieldOffsets may be expensive. However the
330  // "getElementGIDs" can be cheaper. However the lookup for LIDs
331  // may be more expensive!
332 
333  typedef typename PHX::MDField<ScalarT,Cell,NODE>::array_type::reference_type reference_type;
334 
335  if (has_tangent_fields_) {
336  // gather operation for each cell in workset
337  for(std::size_t worksetCellIndex=0;worksetCellIndex<localCellIds.size();++worksetCellIndex) {
338  std::size_t cellLocalId = localCellIds[worksetCellIndex];
339 
340  auto LIDs = globalIndexer_->getElementLIDs(cellLocalId);
341 
342  // loop over the fields to be gathered
343  for (std::size_t fieldIndex=0; fieldIndex<gatherFields_.size();fieldIndex++) {
344  int fieldNum = fieldIds_[fieldIndex];
345  const std::vector<int> & elmtOffset = globalIndexer_->getGIDFieldOffsets(blockId,fieldNum);
346 
347  const std::vector< PHX::MDField<const RealT,Cell,NODE> >& tf_ref =
348  tangentFields_[fieldIndex];
349  const std::size_t num_tf = tf_ref.size();
350 
351  // loop over basis functions and fill the fields
352  for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
353  int offset = elmtOffset[basis];
354  LO lid = LIDs[offset];
355  reference_type gf_ref = (gatherFields_[fieldIndex])(worksetCellIndex,basis);
356  gf_ref.val() = x_array[lid];
357  for (std::size_t i=0; i<num_tf; ++i)
358  gf_ref.fastAccessDx(i) = tf_ref[i](worksetCellIndex,basis);
359  }
360  }
361  }
362  }
363  else {
364  // gather operation for each cell in workset
365  for(std::size_t worksetCellIndex=0;worksetCellIndex<localCellIds.size();++worksetCellIndex) {
366  std::size_t cellLocalId = localCellIds[worksetCellIndex];
367 
368  auto LIDs = globalIndexer_->getElementLIDs(cellLocalId);
369 
370  // loop over the fields to be gathered
371  for (std::size_t fieldIndex=0; fieldIndex<gatherFields_.size();fieldIndex++) {
372  int fieldNum = fieldIds_[fieldIndex];
373  const std::vector<int> & elmtOffset = globalIndexer_->getGIDFieldOffsets(blockId,fieldNum);
374 
375  // loop over basis functions and fill the fields
376  for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
377  int offset = elmtOffset[basis];
378  LO lid = LIDs[offset];
379  reference_type gf_ref = (gatherFields_[fieldIndex])(worksetCellIndex,basis);
380  gf_ref.val() = x_array[lid];
381  }
382  }
383  }
384  }
385 }
386 
387 // **********************************************************************
388 // Specialization: Jacobian
389 // **********************************************************************
390 
391 template<typename TRAITS,typename LO,typename GO,typename NodeT>
394  const Teuchos::RCP<const panzer::GlobalIndexer> & indexer,
395  const Teuchos::ParameterList& p)
396  : globalIndexer_(indexer)
397 {
398  // typedef std::vector< std::vector<std::string> > vvstring;
399 
400  GatherSolution_Input input;
401  input.setParameterList(p);
402 
403  const std::vector<std::string> & names = input.getDofNames();
404  Teuchos::RCP<const panzer::PureBasis> basis = input.getBasis();
405  //const vvstring & tangent_field_names = input.getTangentNames();
406 
407  indexerNames_ = input.getIndexerNames();
408  useTimeDerivativeSolutionVector_ = input.useTimeDerivativeSolutionVector();
409  globalDataKey_ = input.getGlobalDataKey();
410 
411  gatherSeedIndex_ = input.getGatherSeedIndex();
412  sensitivitiesName_ = input.getSensitivitiesName();
413  disableSensitivities_ = !input.firstSensitivitiesAvailable();
414 
415  gatherFields_.resize(names.size());
416  scratch_offsets_.resize(names.size());
417  for (std::size_t fd = 0; fd < names.size(); ++fd) {
418  PHX::MDField<ScalarT,Cell,NODE> f(names[fd],basis->functional);
419  gatherFields_[fd] = f;
420  this->addEvaluatedField(gatherFields_[fd]);
421  // Don't allow for sharing so that we can avoid zeroing out the
422  // off-diagonal values of the FAD derivative array.
423  this->addUnsharedField(gatherFields_[fd].fieldTag().clone());
424  }
425 
426  // figure out what the first active name is
427  std::string firstName = "<none>";
428  if(names.size()>0)
429  firstName = names[0];
430 
431  // print out convenience
432  if(disableSensitivities_) {
433  std::string n = "GatherSolution (Tpetra, No Sensitivities): "+firstName+" (Jacobian)";
434  this->setName(n);
435  }
436  else {
437  std::string n = "GatherSolution (Tpetra): "+firstName+" (Jacobian) ";
438  this->setName(n);
439  }
440 }
441 
442 // **********************************************************************
443 template<typename TRAITS,typename LO,typename GO,typename NodeT>
445 postRegistrationSetup(typename TRAITS::SetupData d,
446  PHX::FieldManager<TRAITS>& /* fm */)
447 {
448  TEUCHOS_ASSERT(gatherFields_.size() == indexerNames_.size());
449 
450  fieldIds_.resize(gatherFields_.size());
451 
452  const Workset & workset_0 = (*d.worksets_)[0];
453  std::string blockId = this->wda(workset_0).block_id;
454 
455  for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) {
456  // get field ID from DOF manager
457  const std::string& fieldName = indexerNames_[fd];
458  fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
459 
460  int fieldNum = fieldIds_[fd];
461  const std::vector<int> & offsets = globalIndexer_->getGIDFieldOffsets(blockId,fieldNum);
462  scratch_offsets_[fd] = PHX::View<int*>("offsets",offsets.size());
463  Kokkos::deep_copy(scratch_offsets_[fd], Kokkos::View<const int*, Kokkos::HostSpace, Kokkos::MemoryUnmanaged>(offsets.data(), offsets.size()));
464  }
465 
466  scratch_lids_ = PHX::View<LO**>("lids",gatherFields_[0].extent(0),
467  globalIndexer_->getElementBlockGIDCount(blockId));
468 
469  indexerNames_.clear(); // Don't need this anymore
470 }
471 
472 // **********************************************************************
473 template<typename TRAITS,typename LO,typename GO,typename NodeT>
475 preEvaluate(typename TRAITS::PreEvalData d)
476 {
477  using Teuchos::RCP;
478  using Teuchos::rcp;
479  using Teuchos::rcp_dynamic_cast;
480 
483 
484  // manage sensitivities
486  if(!disableSensitivities_) {
487  if(d.first_sensitivities_name==sensitivitiesName_)
488  applySensitivities_ = true;
489  else
490  applySensitivities_ = false;
491  }
492  else
493  applySensitivities_ = false;
494 
496 
497  RCP<GlobalEvaluationData> ged;
498 
499  // first try refactored ReadOnly container
500  std::string post = useTimeDerivativeSolutionVector_ ? " - Xdot" : " - X";
501  if(d.gedc->containsDataObject(globalDataKey_+post)) {
502  ged = d.gedc->getDataObject(globalDataKey_+post);
503 
504  RCP<RO_GED> ro_ged = rcp_dynamic_cast<RO_GED>(ged,true);
505 
506  x_vector = ro_ged->getGhostedVector_Tpetra();
507 
508  return;
509  }
510 
511  ged = d.gedc->getDataObject(globalDataKey_);
512 
513  // try to extract linear object container
514  {
515  RCP<LOC> tpetraContainer = rcp_dynamic_cast<LOC>(ged);
516  RCP<LOCPair_GlobalEvaluationData> loc_pair = rcp_dynamic_cast<LOCPair_GlobalEvaluationData>(ged);
517 
518  if(loc_pair!=Teuchos::null) {
519  Teuchos::RCP<LinearObjContainer> loc = loc_pair->getGhostedLOC();
520  // extract linear object container
521  tpetraContainer = rcp_dynamic_cast<LOC>(loc);
522  }
523 
524  if(tpetraContainer!=Teuchos::null) {
525  if (useTimeDerivativeSolutionVector_)
526  x_vector = tpetraContainer->get_dxdt();
527  else
528  x_vector = tpetraContainer->get_x();
529 
530  return; // epetraContainer was found
531  }
532  }
533 
534  // try to extract an EpetraVector_ReadOnly object (this is the last resort!, it throws if not found)
535  {
536  RCP<RO_GED> ro_ged = rcp_dynamic_cast<RO_GED>(ged,true);
537 
538  x_vector = ro_ged->getGhostedVector_Tpetra();
539  }
540 }
541 
542 // **********************************************************************
543 template<typename TRAITS,typename LO,typename GO,typename NodeT>
545 evaluateFields(typename TRAITS::EvalData workset)
546 {
547  // for convenience pull out some objects from workset
548  std::string blockId = this->wda(workset).block_id;
549 
550  double seed_value = 0.0;
551  if (useTimeDerivativeSolutionVector_) {
552  seed_value = workset.alpha;
553  }
554  else if (gatherSeedIndex_<0) {
555  seed_value = workset.beta;
556  }
557  else if(!useTimeDerivativeSolutionVector_) {
558  seed_value = workset.gather_seeds[gatherSeedIndex_];
559  }
560  else {
561  TEUCHOS_ASSERT(false);
562  }
563 
564  // turn off sensitivies: this may be faster if we don't expand the term
565  // but I suspect not because anywhere it is used the full complement of
566  // sensitivies will be needed anyway.
567  if(!applySensitivities_)
568  seed_value = 0.0;
569 
570  // Interface worksets handle DOFs from two element blocks. The
571  // derivative offset for the other element block must be shifted by
572  // the derivative side of my element block.
573  functor_data.dos = 0;
574  if (this->wda.getDetailsIndex() == 1)
575  {
576  // Get the DOF count for my element block.
577  functor_data.dos = globalIndexer_->getElementBlockGIDCount(workset.details(0).block_id);
578  }
579 
580  // switch to a faster assembly
581  bool use_seed = true;
582  if(seed_value==0.0)
583  use_seed = false;
584 
585  globalIndexer_->getElementLIDs(this->wda(workset).cell_local_ids_k,scratch_lids_);
586 
587  // now setup the fuctor_data, and run the parallel_for loop
589 
590  functor_data.x_data = x_vector->getLocalViewDevice(Tpetra::Access::ReadOnly);
591  functor_data.seed_value = seed_value;
592  functor_data.lids = scratch_lids_;
593 
594  // loop over the fields to be gathered
595  for(std::size_t fieldIndex=0;
596  fieldIndex<gatherFields_.size();fieldIndex++) {
597 
598  // setup functor data
599  functor_data.offsets = scratch_offsets_[fieldIndex];
600  functor_data.field = gatherFields_[fieldIndex];
601 
602  if(use_seed)
603  Kokkos::parallel_for(workset.num_cells,*this);
604  else
605  Kokkos::parallel_for(Kokkos::RangePolicy<PHX::Device,NoSeed>(0,workset.num_cells),*this);
606  }
607  functor_data.x_data = Kokkos::View<const double**, Kokkos::LayoutLeft,PHX::Device>();
608 }
609 
610 // **********************************************************************
611 template<typename TRAITS,typename LO,typename GO,typename NodeT>
612 KOKKOS_INLINE_FUNCTION
614 operator()(const int worksetCellIndex) const
615 {
616  // loop over basis functions and fill the fields
617  for(std::size_t basis=0;basis<functor_data.offsets.extent(0);basis++) {
618  int offset = functor_data.offsets(basis);
619  LO lid = functor_data.lids(worksetCellIndex,offset);
620 
621  // set the value and seed the FAD object
622  if (functor_data.dos == 0)
623  functor_data.field(worksetCellIndex,basis).val() = functor_data.x_data(lid,0);
624  else // Interface conditions need to zero out derivative array
625  functor_data.field(worksetCellIndex,basis) = ScalarT(functor_data.x_data(lid,0));
626 
627  functor_data.field(worksetCellIndex,basis).fastAccessDx(functor_data.dos + offset) = functor_data.seed_value;
628  }
629 }
630 
631 // **********************************************************************
632 template<typename TRAITS,typename LO,typename GO,typename NodeT>
633 KOKKOS_INLINE_FUNCTION
635 operator()(const NoSeed,const int worksetCellIndex) const
636 {
637  // loop over basis functions and fill the fields
638  for(std::size_t basis=0;basis<functor_data.offsets.extent(0);basis++) {
639  int offset = functor_data.offsets(basis);
640  LO lid = functor_data.lids(worksetCellIndex,offset);
641 
642  // set the value and seed the FAD object
643  functor_data.field(worksetCellIndex,basis).val() = functor_data.x_data(lid,0);
644  }
645 }
646 
647 // **********************************************************************
648 
649 #endif
std::string getGlobalDataKey() const
Name of the global evaluation data container to use for the source vector (all types) ...
Teuchos::RCP< const PureBasis > getBasis() const
Basis definiting layout of dof names (all types)
void setParameterList(const Teuchos::ParameterList &pl)
const std::vector< std::string > & getDofNames() const
The names of the DOFs to be gathered (all types)
PHX::View< const int * > offsets
int getGatherSeedIndex() const
What index to use for initializing the seed (Jacobian and Hessian)
bool useTimeDerivativeSolutionVector() const
Gather a time derivative vector? (all types)
Gathers solution values from the Newton solution vector into the nodal fields of the field manager...
bool firstSensitivitiesAvailable()
Are first derivative sensitivities enabled or disabled? (Jacobian and Hessian)
Teuchos::RCP< VectorType > getGhostedVector_Tpetra() const
Get the ghosted vector (Tpetra version)
std::string block_id
DEPRECATED - use: getElementBlock()
Teuchos::RCP< LinearObjContainer > getGhostedLOC() const
const Teuchos::RCP< VectorType > get_dxdt() const
std::string getSensitivitiesName() const
The name of the sensitivities. Enables sensitivities at "preEvaluate" time (Jacobian and Hessian) ...
const std::vector< std::string > & getIndexerNames() const
const std::vector< std::vector< std::string > > & getTangentNames() const
Get the name of the tangent fields (tangent only)
PHX::View< const LO ** > lids