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