Panzer Version of the Day
Loading...
Searching...
No Matches
Panzer_GatherSolution_Tpetra_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_GATHER_SOLUTION_TPETRA_IMPL_HPP
12#define PANZER_GATHER_SOLUTION_TPETRA_IMPL_HPP
13
14#include "Teuchos_Assert.hpp"
15#include "Phalanx_DataLayout.hpp"
16
18#include "Panzer_PureBasis.hpp"
24#include "Panzer_DOFManager.hpp"
25
26#include "Teuchos_FancyOStream.hpp"
27
28#include "Tpetra_Vector.hpp"
29#include "Tpetra_Map.hpp"
30
31// **********************************************************************
32// Specialization: Residual
33// **********************************************************************
34
35template<typename TRAITS,typename LO,typename GO,typename NodeT>
38 const Teuchos::RCP<const panzer::GlobalIndexer> & indexer,
39 const Teuchos::ParameterList& p)
40 : globalIndexer_(indexer)
41 , has_tangent_fields_(false)
42{
43 typedef std::vector< std::vector<std::string> > vvstring;
44
46 input.setParameterList(p);
47
48 const std::vector<std::string> & names = input.getDofNames();
49 Teuchos::RCP<const panzer::PureBasis> basis = input.getBasis();
50 const vvstring & tangent_field_names = input.getTangentNames();
51
52 indexerNames_ = input.getIndexerNames();
53 useTimeDerivativeSolutionVector_ = input.useTimeDerivativeSolutionVector();
54 globalDataKey_ = input.getGlobalDataKey();
55
56 // allocate fields
57 gatherFields_.resize(names.size());
58 for (std::size_t fd = 0; fd < names.size(); ++fd) {
59 gatherFields_[fd] =
60 PHX::MDField<ScalarT,Cell,NODE>(names[fd],basis->functional);
61 this->addEvaluatedField(gatherFields_[fd]);
62 }
63
64 // Setup dependent tangent fields if requested
65 if (tangent_field_names.size()>0) {
66 TEUCHOS_ASSERT(gatherFields_.size() == tangent_field_names.size());
67
68 has_tangent_fields_ = true;
69 tangentFields_.resize(gatherFields_.size());
70 for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) {
71 tangentFields_[fd].resize(tangent_field_names[fd].size());
72 for (std::size_t i=0; i<tangent_field_names[fd].size(); ++i) {
73 tangentFields_[fd][i] =
74 PHX::MDField<const ScalarT,Cell,NODE>(tangent_field_names[fd][i],basis->functional);
75 this->addDependentField(tangentFields_[fd][i]);
76 }
77 }
78 }
79
80 // figure out what the first active name is
81 std::string firstName = "<none>";
82 if(names.size()>0)
83 firstName = names[0];
84
85 std::string n = "GatherSolution (Tpetra): "+firstName+" (Residual)";
86 this->setName(n);
87}
88
89// **********************************************************************
90template<typename TRAITS,typename LO,typename GO,typename NodeT>
92postRegistrationSetup(typename TRAITS::SetupData d,
94{
95 TEUCHOS_ASSERT(gatherFields_.size() == indexerNames_.size());
96
97 fieldIds_.resize(gatherFields_.size());
98
99 const Workset & workset_0 = (*d.worksets_)[0];
100 std::string blockId = this->wda(workset_0).block_id;
101 scratch_offsets_.resize(gatherFields_.size());
102
103 for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) {
104 const std::string& fieldName = indexerNames_[fd];
105 fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
106
107 int fieldNum = fieldIds_[fd];
108 const std::vector<int> & offsets = globalIndexer_->getGIDFieldOffsets(blockId,fieldNum);
109 scratch_offsets_[fd] = PHX::View<int*>("offsets",offsets.size());
110 Kokkos::deep_copy(scratch_offsets_[fd], Kokkos::View<const int*, Kokkos::HostSpace, Kokkos::MemoryUnmanaged>(offsets.data(), offsets.size()));
111 }
112
113 scratch_lids_ = PHX::View<LO**>("lids",gatherFields_[0].extent(0),
114 globalIndexer_->getElementBlockGIDCount(blockId));
115
116 indexerNames_.clear(); // Don't need this anymore
117}
118
119// **********************************************************************
120template<typename TRAITS,typename LO,typename GO,typename NodeT>
122preEvaluate(typename TRAITS::PreEvalData d)
123{
126
127 // first try the refactored read-only container
128 std::string post = useTimeDerivativeSolutionVector_ ? " - Xdot" : " - X";
129 if(d.gedc->containsDataObject(globalDataKey_+post)) {
130 x_vector = Teuchos::rcp_dynamic_cast<RO_GED>(d.gedc->getDataObject(globalDataKey_+post),true)->getGhostedVector_Tpetra();
131 return;
132 }
133
134 Teuchos::RCP<GlobalEvaluationData> ged = d.gedc->getDataObject(globalDataKey_);
135
136 // extract linear object container
137 tpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(ged);
138
139 if(tpetraContainer_==Teuchos::null) {
140 Teuchos::RCP<LOCPair_GlobalEvaluationData> loc_pair = Teuchos::rcp_dynamic_cast<LOCPair_GlobalEvaluationData>(ged);
141 if(loc_pair!=Teuchos::null)
142 tpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(loc_pair->getGhostedLOC());
143 }
144
145 if(tpetraContainer_!=Teuchos::null) {
146 x_vector = useTimeDerivativeSolutionVector_ ? tpetraContainer_->get_dxdt_mv()
147 : tpetraContainer_->get_x_mv();
148 return;
149 }
150
151 // last resort: a read-only ghosted vector stored under the bare key. This
152 // throws if the object is neither, which is the intended behavior.
153 x_vector = Teuchos::rcp_dynamic_cast<RO_GED>(ged,true)->getGhostedVector_Tpetra();
154}
155
156// **********************************************************************
157template<typename TRAITS,typename LO,typename GO,typename NodeT>
159evaluateFields(typename TRAITS::EvalData workset)
160{
161 // for convenience pull out some objects from workset
162 std::string blockId = this->wda(workset).block_id;
163 const std::vector<std::size_t> & localCellIds = this->wda(workset).cell_local_ids;
164
165 auto x_data = x_vector->getLocalViewDevice(Tpetra::Access::ReadOnly);
166
167 globalIndexer_->getElementLIDs(this->wda(workset).cell_local_ids_k,scratch_lids_);
168
169 // NOTE: A reordering of these loops will likely improve performance
170 // The "getGIDFieldOffsets may be expensive. However the
171 // "getElementGIDs" can be cheaper. However the lookup for LIDs
172 // may be more expensive!
173
174 // gather operation for each cell in workset
175
176 auto lids = scratch_lids_;
177 for (std::size_t fieldIndex=0; fieldIndex<gatherFields_.size();fieldIndex++) {
178 auto offsets = scratch_offsets_[fieldIndex];
179 auto gather_field = gatherFields_[fieldIndex].get_static_view();
180
181 Kokkos::parallel_for(localCellIds.size(), KOKKOS_LAMBDA (std::size_t worksetCellIndex) {
182 // loop over basis functions and fill the fields
183 for(std::size_t basis=0;basis<offsets.extent(0);basis++) {
184 int offset = offsets(basis);
185 LO lid = lids(worksetCellIndex,offset);
186
187 // set the value and seed the FAD object
188 gather_field(worksetCellIndex,basis) = x_data(lid,0);
189 }
190 });
191 }
192}
193
194// **********************************************************************
195// Specialization: Tangent
196// **********************************************************************
197
198template<typename TRAITS,typename LO,typename GO,typename NodeT>
201 const Teuchos::RCP<const panzer::GlobalIndexer> & indexer,
202 const Teuchos::ParameterList& p)
203 : globalIndexer_(indexer)
204 , has_tangent_fields_(false)
205{
206 typedef std::vector< std::vector<std::string> > vvstring;
207
209 input.setParameterList(p);
210
211 const std::vector<std::string> & names = input.getDofNames();
212 Teuchos::RCP<const panzer::PureBasis> basis = input.getBasis();
213 const vvstring & tangent_field_names = input.getTangentNames();
214
215 indexerNames_ = input.getIndexerNames();
216 useTimeDerivativeSolutionVector_ = input.useTimeDerivativeSolutionVector();
217 globalDataKey_ = input.getGlobalDataKey();
218
219 // allocate fields
220 gatherFields_.resize(names.size());
221 for (std::size_t fd = 0; fd < names.size(); ++fd) {
222 gatherFields_[fd] =
223 PHX::MDField<ScalarT,Cell,NODE>(names[fd],basis->functional);
224 this->addEvaluatedField(gatherFields_[fd]);
225 // Don't allow for sharing so that we can avoid zeroing out the
226 // off-diagonal values of the FAD derivative array.
227 this->addUnsharedField(gatherFields_[fd].fieldTag().clone());
228 }
229
230 // Setup dependent tangent fields if requested
231 if (tangent_field_names.size()>0) {
232 TEUCHOS_ASSERT(gatherFields_.size() == tangent_field_names.size());
233
234 has_tangent_fields_ = true;
235 tangentFields_.resize(gatherFields_.size());
236 for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) {
237 tangentFields_[fd].resize(tangent_field_names[fd].size());
238 for (std::size_t i=0; i<tangent_field_names[fd].size(); ++i) {
239 tangentFields_[fd][i] =
240 PHX::MDField<const RealT,Cell,NODE>(tangent_field_names[fd][i],basis->functional);
241 this->addDependentField(tangentFields_[fd][i]);
242 }
243 }
244 }
245
246 // figure out what the first active name is
247 std::string firstName = "<none>";
248 if(names.size()>0)
249 firstName = names[0];
250
251 std::string n = "GatherSolution (Tpetra): "+firstName+" (Tangent)";
252 this->setName(n);
253}
254
255// **********************************************************************
256template<typename TRAITS,typename LO,typename GO,typename NodeT>
258postRegistrationSetup(typename TRAITS::SetupData /* d */,
260{
261 TEUCHOS_ASSERT(gatherFields_.size() == indexerNames_.size());
262
263 fieldIds_.resize(gatherFields_.size());
264
265 // Original implementation of tangentFields used vector of
266 // vectors. The inner vectors could have different sizes for each
267 // [fd]. With UVM removal, we need to use a rank 2 view of views. So
268 // we need an extra vector to carry around the inner vector sizes.
269 tangentInnerVectorSizes_ = PHX::View<size_t*>("tangentInnerVectorSizes_",gatherFields_.size());
270 auto tangentInnerVectorSizes_host = Kokkos::create_mirror_view(tangentInnerVectorSizes_);
271 size_t inner_vector_max_size = 0;
272 for (std::size_t fd = 0; fd < tangentFields_.size(); ++fd) {
273 inner_vector_max_size = std::max(inner_vector_max_size,tangentFields_[fd].size());
274 tangentInnerVectorSizes_host(fd) = tangentFields_[fd].size();
275 }
276 Kokkos::deep_copy(tangentInnerVectorSizes_,tangentInnerVectorSizes_host);
277
278 gatherFieldsVoV_.initialize("GatherSolution_Tpetra<Tangent>::gatherFieldsVoV_",gatherFields_.size());
279 tangentFieldsVoV_.initialize("GatherSolution_Tpetra<Tangent>::tangentFieldsVoV_",gatherFields_.size(),inner_vector_max_size);
280
281 for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) {
282 const std::string& fieldName = indexerNames_[fd];
283 fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
284 gatherFieldsVoV_.addView(gatherFields_[fd].get_static_view(),fd);
285
286 if (has_tangent_fields_) {
287 for (std::size_t i=0; i<tangentFields_[fd].size(); ++i) {
288 tangentFieldsVoV_.addView(tangentFields_[fd][i].get_static_view(),fd,i);
289 }
290 }
291 }
292
293 gatherFieldsVoV_.syncHostToDevice();
294 tangentFieldsVoV_.syncHostToDevice();
295
296 indexerNames_.clear(); // Don't need this anymore
297}
298
299// **********************************************************************
300template<typename TRAITS,typename LO,typename GO,typename NodeT>
302preEvaluate(typename TRAITS::PreEvalData d)
303{
306
307 // first try the refactored read-only container
308 std::string post = useTimeDerivativeSolutionVector_ ? " - Xdot" : " - X";
309 if(d.gedc->containsDataObject(globalDataKey_+post)) {
310 x_vector = Teuchos::rcp_dynamic_cast<RO_GED>(d.gedc->getDataObject(globalDataKey_+post),true)->getGhostedVector_Tpetra();
311 return;
312 }
313
314 Teuchos::RCP<GlobalEvaluationData> ged = d.gedc->getDataObject(globalDataKey_);
315
316 // extract linear object container
317 tpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(ged);
318
319 if(tpetraContainer_==Teuchos::null) {
320 Teuchos::RCP<LOCPair_GlobalEvaluationData> loc_pair = Teuchos::rcp_dynamic_cast<LOCPair_GlobalEvaluationData>(ged);
321 if(loc_pair!=Teuchos::null)
322 tpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(loc_pair->getGhostedLOC());
323 }
324
325 if(tpetraContainer_!=Teuchos::null) {
326 x_vector = useTimeDerivativeSolutionVector_ ? tpetraContainer_->get_dxdt_mv()
327 : tpetraContainer_->get_x_mv();
328 return;
329 }
330
331 // last resort: a read-only ghosted vector stored under the bare key. This
332 // throws if the object is neither, which is the intended behavior.
333 x_vector = Teuchos::rcp_dynamic_cast<RO_GED>(ged,true)->getGhostedVector_Tpetra();
334}
335
336// **********************************************************************
337template<typename TRAITS,typename LO,typename GO,typename NodeT>
339evaluateFields(typename TRAITS::EvalData workset)
340{
341 // for convenience pull out some objects from workset
342 std::string blockId = this->wda(workset).block_id;
343
344 typedef typename PHX::MDField<ScalarT,Cell,NODE>::array_type::reference_type reference_type;
345 auto cellLocalIdsKokkos = this->wda(workset).getLocalCellIDs();
346 auto lids = globalIndexer_->getLIDs();
347 auto gidFieldOffsetsVoV = Teuchos::rcp_dynamic_cast<const panzer::DOFManager>(globalIndexer_,true)->getGIDFieldOffsetsKokkos(blockId,fieldIds_);
348 auto gidFieldOffsets = gidFieldOffsetsVoV.getViewDevice();
349 auto gatherFieldsDevice = gatherFieldsVoV_.getViewDevice();
350 auto x_view = x_vector->getLocalViewDevice(Tpetra::Access::ReadOnly);
351 auto tangentInnerVectorSizes = this->tangentInnerVectorSizes_;
352
353 if (has_tangent_fields_) {
354 auto tangentFieldsDevice = tangentFieldsVoV_.getViewDevice();
355 Kokkos::parallel_for("GatherSolutionTpetra<Tangent>",cellLocalIdsKokkos.extent(0),KOKKOS_LAMBDA(const int worksetCellIndex) {
356 for (size_t fieldIndex = 0; fieldIndex < gidFieldOffsets.extent(0); ++fieldIndex) {
357 for(size_t basis=0;basis<gidFieldOffsets(fieldIndex).extent(0);basis++) {
358 int offset = gidFieldOffsets(fieldIndex)(basis);
359 LO lid = lids(cellLocalIdsKokkos(worksetCellIndex),offset);
360 auto gf_ref = (gatherFieldsDevice[fieldIndex])(worksetCellIndex,basis);
361 gf_ref.val() = x_view(lid,0);
362 for (std::size_t i=0; i<tangentInnerVectorSizes(fieldIndex); ++i) {
363 gf_ref.fastAccessDx(i) = tangentFieldsDevice(fieldIndex,i)(worksetCellIndex,basis);
364 }
365 }
366 }
367 });
368 }
369 else {
370 Kokkos::parallel_for("GatherSolutionTpetra<Tangent>",cellLocalIdsKokkos.extent(0),KOKKOS_LAMBDA(const int worksetCellIndex) {
371 for (size_t fieldIndex = 0; fieldIndex < gidFieldOffsets.extent(0); ++fieldIndex) {
372 for(size_t basis=0;basis<gidFieldOffsets(fieldIndex).extent(0);basis++) {
373 int offset = gidFieldOffsets(fieldIndex)(basis);
374 LO lid = lids(cellLocalIdsKokkos(worksetCellIndex),offset);
375 reference_type gf_ref = (gatherFieldsDevice[fieldIndex])(worksetCellIndex,basis);
376 gf_ref.val() = x_view(lid,0);
377 }
378 }
379 });
380 }
381}
382
383// **********************************************************************
384// Specialization: Jacobian
385// **********************************************************************
386
387template<typename TRAITS,typename LO,typename GO,typename NodeT>
390 const Teuchos::RCP<const panzer::GlobalIndexer> & indexer,
391 const Teuchos::ParameterList& p)
392 : globalIndexer_(indexer)
393{
394 // typedef std::vector< std::vector<std::string> > vvstring;
395
397 input.setParameterList(p);
398
399 const std::vector<std::string> & names = input.getDofNames();
400 Teuchos::RCP<const panzer::PureBasis> basis = input.getBasis();
401 //const vvstring & tangent_field_names = input.getTangentNames();
402
403 indexerNames_ = input.getIndexerNames();
404 useTimeDerivativeSolutionVector_ = input.useTimeDerivativeSolutionVector();
405 globalDataKey_ = input.getGlobalDataKey();
406
407 gatherSeedIndex_ = input.getGatherSeedIndex();
408 sensitivitiesName_ = input.getSensitivitiesName();
409 disableSensitivities_ = !input.firstSensitivitiesAvailable();
410
411 gatherFields_.resize(names.size());
412 scratch_offsets_.resize(names.size());
413 for (std::size_t fd = 0; fd < names.size(); ++fd) {
414 PHX::MDField<ScalarT,Cell,NODE> f(names[fd],basis->functional);
415 gatherFields_[fd] = f;
416 this->addEvaluatedField(gatherFields_[fd]);
417 // Don't allow for sharing so that we can avoid zeroing out the
418 // off-diagonal values of the FAD derivative array.
419 this->addUnsharedField(gatherFields_[fd].fieldTag().clone());
420 }
421
422 // figure out what the first active name is
423 std::string firstName = "<none>";
424 if(names.size()>0)
425 firstName = names[0];
426
427 // print out convenience
428 if(disableSensitivities_) {
429 std::string n = "GatherSolution (Tpetra, No Sensitivities): "+firstName+" (Jacobian)";
430 this->setName(n);
431 }
432 else {
433 std::string n = "GatherSolution (Tpetra): "+firstName+" (Jacobian) ";
434 this->setName(n);
435 }
436}
437
438// **********************************************************************
439template<typename TRAITS,typename LO,typename GO,typename NodeT>
441postRegistrationSetup(typename TRAITS::SetupData d,
443{
444 TEUCHOS_ASSERT(gatherFields_.size() == indexerNames_.size());
445
446 fieldIds_.resize(gatherFields_.size());
447
448 const Workset & workset_0 = (*d.worksets_)[0];
449 std::string blockId = this->wda(workset_0).block_id;
450
451 for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) {
452 // get field ID from DOF manager
453 const std::string& fieldName = indexerNames_[fd];
454 fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
455
456 int fieldNum = fieldIds_[fd];
457 const std::vector<int> & offsets = globalIndexer_->getGIDFieldOffsets(blockId,fieldNum);
458 scratch_offsets_[fd] = PHX::View<int*>("offsets",offsets.size());
459 Kokkos::deep_copy(scratch_offsets_[fd], Kokkos::View<const int*, Kokkos::HostSpace, Kokkos::MemoryUnmanaged>(offsets.data(), offsets.size()));
460 }
461
462 scratch_lids_ = PHX::View<LO**>("lids",gatherFields_[0].extent(0),
463 globalIndexer_->getElementBlockGIDCount(blockId));
464
465 indexerNames_.clear(); // Don't need this anymore
466}
467
468// **********************************************************************
469template<typename TRAITS,typename LO,typename GO,typename NodeT>
471preEvaluate(typename TRAITS::PreEvalData d)
472{
473 using Teuchos::RCP;
474 using Teuchos::rcp;
475 using Teuchos::rcp_dynamic_cast;
476
479
480 // manage sensitivities
482 if(!disableSensitivities_) {
483 if(d.first_sensitivities_name==sensitivitiesName_)
484 applySensitivities_ = true;
485 else
486 applySensitivities_ = false;
487 }
488 else
489 applySensitivities_ = false;
490
492
493 RCP<GlobalEvaluationData> ged;
494
495 // first try refactored ReadOnly container
496 std::string post = useTimeDerivativeSolutionVector_ ? " - Xdot" : " - X";
497 if(d.gedc->containsDataObject(globalDataKey_+post)) {
498 ged = d.gedc->getDataObject(globalDataKey_+post);
499
500 RCP<RO_GED> ro_ged = rcp_dynamic_cast<RO_GED>(ged,true);
501
502 x_vector = ro_ged->getGhostedVector_Tpetra();
503
504 return;
505 }
506
507 ged = d.gedc->getDataObject(globalDataKey_);
508
509 // try to extract linear object container
510 {
511 RCP<LOC> tpetraContainer = rcp_dynamic_cast<LOC>(ged);
512 RCP<LOCPair_GlobalEvaluationData> loc_pair = rcp_dynamic_cast<LOCPair_GlobalEvaluationData>(ged);
513
514 if(loc_pair!=Teuchos::null) {
515 Teuchos::RCP<LinearObjContainer> loc = loc_pair->getGhostedLOC();
516 // extract linear object container
517 tpetraContainer = rcp_dynamic_cast<LOC>(loc);
518 }
519
520 if(tpetraContainer!=Teuchos::null) {
521 if (useTimeDerivativeSolutionVector_)
522 x_vector = tpetraContainer->get_dxdt_mv();
523 else
524 x_vector = tpetraContainer->get_x_mv();
525
526 return; // epetraContainer was found
527 }
528 }
529
530 // try to extract an EpetraVector_ReadOnly object (this is the last resort!, it throws if not found)
531 {
532 RCP<RO_GED> ro_ged = rcp_dynamic_cast<RO_GED>(ged,true);
533
534 x_vector = ro_ged->getGhostedVector_Tpetra();
535 }
536}
537
538// **********************************************************************
539template<typename TRAITS,typename LO,typename GO,typename NodeT>
541evaluateFields(typename TRAITS::EvalData workset)
542{
543 // for convenience pull out some objects from workset
544 std::string blockId = this->wda(workset).block_id;
545
546 // Only read the seed when it will actually be used. With sensitivities off
547 // the gather_seeds entry this index names need not exist: a gather built
548 // with a seed index still runs on every evaluation, and only the ones the
549 // model evaluator is differentiating with respect to get seeds filled in.
550 double seed_value = 0.0;
551 if (applySensitivities_) {
552 if (useTimeDerivativeSolutionVector_) {
553 seed_value = workset.alpha;
554 }
555 else if (gatherSeedIndex_<0) {
556 seed_value = workset.beta;
557 }
558 else if(!useTimeDerivativeSolutionVector_) {
559 seed_value = workset.gather_seeds[gatherSeedIndex_];
560 }
561 else {
562 TEUCHOS_ASSERT(false);
563 }
564 }
565
566 // Interface worksets handle DOFs from two element blocks. The
567 // derivative offset for the other element block must be shifted by
568 // the derivative side of my element block.
569 functor_data.dos = 0;
570 if (this->wda.getDetailsIndex() == 1)
571 {
572 // Get the DOF count for my element block.
573 functor_data.dos = globalIndexer_->getElementBlockGIDCount(workset.details(0).block_id);
574 }
575
576 globalIndexer_->getElementLIDs(this->wda(workset).cell_local_ids_k,scratch_lids_);
577
578 // now setup the fuctor_data, and run the parallel_for loop
580
581 functor_data.x_data = x_vector->getLocalViewDevice(Tpetra::Access::ReadOnly);
582 functor_data.seed_value = seed_value;
583 functor_data.lids = scratch_lids_;
584
585 // loop over the fields to be gathered
586 for(std::size_t fieldIndex=0;
587 fieldIndex<gatherFields_.size();fieldIndex++) {
588
589 // setup functor data
590 functor_data.offsets = scratch_offsets_[fieldIndex];
591 functor_data.field = gatherFields_[fieldIndex];
592
593 Kokkos::parallel_for(workset.num_cells,*this);
594 }
595 functor_data.x_data = Kokkos::View<const double**, Kokkos::LayoutLeft,PHX::Device>();
596}
597
598// **********************************************************************
599template<typename TRAITS,typename LO,typename GO,typename NodeT>
600KOKKOS_INLINE_FUNCTION
602operator()(const int worksetCellIndex) const
603{
604 // loop over basis functions and fill the fields
605 for(std::size_t basis=0;basis<functor_data.offsets.extent(0);basis++) {
606 int offset = functor_data.offsets(basis);
607 LO lid = functor_data.lids(worksetCellIndex,offset);
608
609 // set the value and seed the FAD object
610 if (functor_data.dos == 0)
611 functor_data.field(worksetCellIndex,basis).val() = functor_data.x_data(lid,0);
612 else // Interface conditions need to zero out derivative array
613 functor_data.field(worksetCellIndex,basis) = ScalarT(functor_data.x_data(lid,0));
614
615 // Always written, even when the seed is zero. See operator() in the decl.
616 functor_data.field(worksetCellIndex,basis).fastAccessDx(functor_data.dos + offset) = functor_data.seed_value;
617 }
618}
619
620// **********************************************************************
621
622#endif
PHX::View< const int * > offsets
PHX::View< const LO ** > lids
std::string getGlobalDataKey() const
Name of the global evaluation data container to use for the source vector (all types)
void setParameterList(const Teuchos::ParameterList &pl)
int getGatherSeedIndex() const
What index to use for initializing the seed (Jacobian and Hessian)
const std::vector< std::vector< std::string > > & getTangentNames() const
Get the name of the tangent fields (tangent only)
bool firstSensitivitiesAvailable()
Are first derivative sensitivities enabled or disabled? (Jacobian and Hessian)
bool useTimeDerivativeSolutionVector() const
Gather a time derivative vector? (all types)
const std::vector< std::string > & getIndexerNames() const
std::string getSensitivitiesName() const
The name of the sensitivities. Enables sensitivities at "preEvaluate" time (Jacobian and Hessian)
Teuchos::RCP< const PureBasis > getBasis() const
Basis definiting layout of dof names (all types)
const std::vector< std::string > & getDofNames() const
The names of the DOFs to be gathered (all types)
Gathers solution values from the Newton solution vector into the nodal fields of the field manager.
Tpetra-backed implementation of LinearObjContainer.
Teuchos::RCP< VectorType > getGhostedVector_Tpetra() const
Get the ghosted vector (Tpetra version)
std::string block_id
DEPRECATED - use: getElementBlock()