11 #ifndef PANZER_GATHER_SOLUTION_TPETRA_IMPL_HPP
12 #define PANZER_GATHER_SOLUTION_TPETRA_IMPL_HPP
14 #include "Teuchos_Assert.hpp"
15 #include "Phalanx_DataLayout.hpp"
26 #include "Teuchos_FancyOStream.hpp"
28 #include "Tpetra_Vector.hpp"
29 #include "Tpetra_Map.hpp"
35 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
40 : globalIndexer_(indexer)
41 , has_tangent_fields_(false)
43 typedef std::vector< std::vector<std::string> > vvstring;
48 const std::vector<std::string> & names = input.
getDofNames();
57 gatherFields_.resize(names.size());
58 for (std::size_t fd = 0; fd < names.size(); ++fd) {
61 this->addEvaluatedField(gatherFields_[fd]);
65 if (tangent_field_names.size()>0) {
66 TEUCHOS_ASSERT(gatherFields_.size() == tangent_field_names.size());
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] =
75 this->addDependentField(tangentFields_[fd][i]);
81 std::string firstName =
"<none>";
85 std::string n =
"GatherSolution (Tpetra): "+firstName+
" (Residual)";
90 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
97 fieldIds_.resize(gatherFields_.size());
99 const Workset & workset_0 = (*d.worksets_)[0];
100 std::string blockId = this->wda(workset_0).
block_id;
101 scratch_offsets_.resize(gatherFields_.size());
103 for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) {
104 const std::string& fieldName = indexerNames_[fd];
105 fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
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());
113 scratch_lids_ = PHX::View<LO**>(
"lids",gatherFields_[0].extent(0),
114 globalIndexer_->getElementBlockGIDCount(blockId));
116 indexerNames_.clear();
120 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
127 tpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(d.gedc->getDataObject(globalDataKey_));
129 if(tpetraContainer_==Teuchos::null) {
132 tpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(loc);
137 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
144 std::string blockId = this->wda(workset).block_id;
145 const std::vector<std::size_t> & localCellIds = this->wda(workset).cell_local_ids;
148 if (useTimeDerivativeSolutionVector_)
149 x = tpetraContainer_->get_dxdt();
151 x = tpetraContainer_->get_x();
153 auto x_data = x->getLocalViewDevice(Tpetra::Access::ReadOnly);
155 globalIndexer_->getElementLIDs(this->wda(workset).cell_local_ids_k,scratch_lids_);
164 auto lids = scratch_lids_;
165 for (std::size_t fieldIndex=0; fieldIndex<gatherFields_.size();fieldIndex++) {
166 auto offsets = scratch_offsets_[fieldIndex];
167 auto gather_field = gatherFields_[fieldIndex].get_static_view();
169 Kokkos::parallel_for(localCellIds.size(), KOKKOS_LAMBDA (std::size_t worksetCellIndex) {
171 for(std::size_t basis=0;basis<
offsets.extent(0);basis++) {
173 LO lid =
lids(worksetCellIndex,offset);
176 gather_field(worksetCellIndex,basis) = x_data(lid,0);
186 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
191 : globalIndexer_(indexer)
192 , has_tangent_fields_(false)
194 typedef std::vector< std::vector<std::string> > vvstring;
199 const std::vector<std::string> & names = input.
getDofNames();
208 gatherFields_.resize(names.size());
209 for (std::size_t fd = 0; fd < names.size(); ++fd) {
212 this->addEvaluatedField(gatherFields_[fd]);
215 this->addUnsharedField(gatherFields_[fd].fieldTag().clone());
219 if (tangent_field_names.size()>0) {
220 TEUCHOS_ASSERT(gatherFields_.size() == tangent_field_names.size());
222 has_tangent_fields_ =
true;
223 tangentFields_.resize(gatherFields_.size());
224 for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) {
225 tangentFields_[fd].resize(tangent_field_names[fd].size());
226 for (std::size_t i=0; i<tangent_field_names[fd].size(); ++i) {
227 tangentFields_[fd][i] =
229 this->addDependentField(tangentFields_[fd][i]);
235 std::string firstName =
"<none>";
237 firstName = names[0];
239 std::string n =
"GatherSolution (Tpetra): "+firstName+
" (Tangent)";
244 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
251 fieldIds_.resize(gatherFields_.size());
257 tangentInnerVectorSizes_ = PHX::View<size_t*>(
"tangentInnerVectorSizes_",gatherFields_.size());
258 auto tangentInnerVectorSizes_host = Kokkos::create_mirror_view(tangentInnerVectorSizes_);
259 size_t inner_vector_max_size = 0;
260 for (std::size_t fd = 0; fd < tangentFields_.size(); ++fd) {
261 inner_vector_max_size = std::max(inner_vector_max_size,tangentFields_[fd].size());
262 tangentInnerVectorSizes_host(fd) = tangentFields_[fd].size();
264 Kokkos::deep_copy(tangentInnerVectorSizes_,tangentInnerVectorSizes_host);
266 gatherFieldsVoV_.initialize(
"GatherSolution_Teptra<Tangent>::gatherFieldsVoV_",gatherFields_.size());
267 tangentFieldsVoV_.initialize(
"GatherSolution_Teptra<Tangent>::tangentFieldsVoV_",gatherFields_.size(),inner_vector_max_size);
269 for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) {
270 const std::string& fieldName = indexerNames_[fd];
271 fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
272 gatherFieldsVoV_.addView(gatherFields_[fd].get_static_view(),fd);
274 if (has_tangent_fields_) {
275 for (std::size_t i=0; i<tangentFields_[fd].size(); ++i) {
276 tangentFieldsVoV_.addView(tangentFields_[fd][i].get_static_view(),fd,i);
281 gatherFieldsVoV_.syncHostToDevice();
282 tangentFieldsVoV_.syncHostToDevice();
284 indexerNames_.clear();
288 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
295 tpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(d.gedc->getDataObject(globalDataKey_));
297 if(tpetraContainer_==Teuchos::null) {
300 tpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(loc);
305 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
312 std::string blockId = this->wda(workset).block_id;
315 if (useTimeDerivativeSolutionVector_)
316 x = tpetraContainer_->get_dxdt();
318 x = tpetraContainer_->get_x();
321 auto cellLocalIdsKokkos = this->wda(workset).getLocalCellIDs();
322 auto lids = globalIndexer_->getLIDs();
323 auto gidFieldOffsetsVoV = Teuchos::rcp_dynamic_cast<
const panzer::DOFManager>(globalIndexer_,
true)->getGIDFieldOffsetsKokkos(blockId,fieldIds_);
324 auto gidFieldOffsets = gidFieldOffsetsVoV.getViewDevice();
325 auto gatherFieldsDevice = gatherFieldsVoV_.getViewDevice();
326 auto x_view = x->getLocalViewDevice(Tpetra::Access::ReadOnly);
327 auto tangentInnerVectorSizes = this->tangentInnerVectorSizes_;
329 if (has_tangent_fields_) {
330 auto tangentFieldsDevice = tangentFieldsVoV_.getViewDevice();
331 Kokkos::parallel_for(
"GatherSolutionTpetra<Tangent>",cellLocalIdsKokkos.extent(0),KOKKOS_LAMBDA(
const int worksetCellIndex) {
332 for (
size_t fieldIndex = 0; fieldIndex < gidFieldOffsets.extent(0); ++fieldIndex) {
333 for(
size_t basis=0;basis<gidFieldOffsets(fieldIndex).extent(0);basis++) {
334 int offset = gidFieldOffsets(fieldIndex)(basis);
335 LO lid =
lids(cellLocalIdsKokkos(worksetCellIndex),offset);
336 auto gf_ref = (gatherFieldsDevice[fieldIndex])(worksetCellIndex,basis);
337 gf_ref.val() = x_view(lid,0);
338 for (std::size_t i=0; i<tangentInnerVectorSizes(fieldIndex); ++i) {
339 gf_ref.fastAccessDx(i) = tangentFieldsDevice(fieldIndex,i)(worksetCellIndex,basis);
346 Kokkos::parallel_for(
"GatherSolutionTpetra<Tangent>",cellLocalIdsKokkos.extent(0),KOKKOS_LAMBDA(
const int worksetCellIndex) {
347 for (
size_t fieldIndex = 0; fieldIndex < gidFieldOffsets.extent(0); ++fieldIndex) {
348 for(
size_t basis=0;basis<gidFieldOffsets(fieldIndex).extent(0);basis++) {
349 int offset = gidFieldOffsets(fieldIndex)(basis);
350 LO lid =
lids(cellLocalIdsKokkos(worksetCellIndex),offset);
351 reference_type gf_ref = (gatherFieldsDevice[fieldIndex])(worksetCellIndex,basis);
352 gf_ref.val() = x_view(lid,0);
363 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
368 : globalIndexer_(indexer)
375 const std::vector<std::string> & names = input.
getDofNames();
387 gatherFields_.resize(names.size());
388 scratch_offsets_.resize(names.size());
389 for (std::size_t fd = 0; fd < names.size(); ++fd) {
391 gatherFields_[fd] = f;
392 this->addEvaluatedField(gatherFields_[fd]);
395 this->addUnsharedField(gatherFields_[fd].fieldTag().clone());
399 std::string firstName =
"<none>";
401 firstName = names[0];
404 if(disableSensitivities_) {
405 std::string n =
"GatherSolution (Tpetra, No Sensitivities): "+firstName+
" (Jacobian)";
409 std::string n =
"GatherSolution (Tpetra): "+firstName+
" (Jacobian) ";
415 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
422 fieldIds_.resize(gatherFields_.size());
424 const Workset & workset_0 = (*d.worksets_)[0];
425 std::string blockId = this->wda(workset_0).
block_id;
427 for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) {
429 const std::string& fieldName = indexerNames_[fd];
430 fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
432 int fieldNum = fieldIds_[fd];
433 const std::vector<int> &
offsets = globalIndexer_->getGIDFieldOffsets(blockId,fieldNum);
434 scratch_offsets_[fd] = PHX::View<int*>(
"offsets",offsets.size());
438 scratch_lids_ = PHX::View<LO**>(
"lids",gatherFields_[0].extent(0),
439 globalIndexer_->getElementBlockGIDCount(blockId));
441 indexerNames_.clear();
445 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
451 using Teuchos::rcp_dynamic_cast;
458 if(!disableSensitivities_) {
459 if(d.first_sensitivities_name==sensitivitiesName_)
460 applySensitivities_ =
true;
462 applySensitivities_ =
false;
465 applySensitivities_ =
false;
472 std::string post = useTimeDerivativeSolutionVector_ ?
" - Xdot" :
" - X";
473 if(d.gedc->containsDataObject(globalDataKey_+post)) {
474 ged = d.gedc->getDataObject(globalDataKey_+post);
476 RCP<RO_GED> ro_ged = rcp_dynamic_cast<RO_GED>(ged,
true);
478 x_vector = ro_ged->getGhostedVector_Tpetra();
483 ged = d.gedc->getDataObject(globalDataKey_);
487 RCP<LOC> tpetraContainer = rcp_dynamic_cast<LOC>(ged);
490 if(loc_pair!=Teuchos::null) {
493 tpetraContainer = rcp_dynamic_cast<LOC>(loc);
496 if(tpetraContainer!=Teuchos::null) {
497 if (useTimeDerivativeSolutionVector_)
498 x_vector = tpetraContainer->get_dxdt();
500 x_vector = tpetraContainer->get_x();
508 RCP<RO_GED> ro_ged = rcp_dynamic_cast<RO_GED>(ged,
true);
510 x_vector = ro_ged->getGhostedVector_Tpetra();
515 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
520 std::string blockId = this->wda(workset).block_id;
522 double seed_value = 0.0;
523 if (useTimeDerivativeSolutionVector_) {
524 seed_value = workset.alpha;
526 else if (gatherSeedIndex_<0) {
527 seed_value = workset.beta;
529 else if(!useTimeDerivativeSolutionVector_) {
530 seed_value = workset.gather_seeds[gatherSeedIndex_];
539 if(!applySensitivities_)
545 functor_data.dos = 0;
546 if (this->wda.getDetailsIndex() == 1)
549 functor_data.dos = globalIndexer_->getElementBlockGIDCount(workset.details(0).block_id);
553 bool use_seed =
true;
557 globalIndexer_->getElementLIDs(this->wda(workset).cell_local_ids_k,scratch_lids_);
562 functor_data.x_data = x_vector->getLocalViewDevice(Tpetra::Access::ReadOnly);
563 functor_data.seed_value = seed_value;
564 functor_data.lids = scratch_lids_;
567 for(std::size_t fieldIndex=0;
568 fieldIndex<gatherFields_.size();fieldIndex++) {
571 functor_data.offsets = scratch_offsets_[fieldIndex];
572 functor_data.field = gatherFields_[fieldIndex];
575 Kokkos::parallel_for(workset.num_cells,*
this);
577 Kokkos::parallel_for(Kokkos::RangePolicy<PHX::Device,NoSeed>(0,workset.num_cells),*
this);
583 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
584 KOKKOS_INLINE_FUNCTION
589 for(std::size_t basis=0;basis<functor_data.offsets.extent(0);basis++) {
590 int offset = functor_data.offsets(basis);
591 LO lid = functor_data.lids(worksetCellIndex,offset);
594 if (functor_data.dos == 0)
595 functor_data.field(worksetCellIndex,basis).val() = functor_data.x_data(lid,0);
597 functor_data.field(worksetCellIndex,basis) =
ScalarT(functor_data.x_data(lid,0));
599 functor_data.field(worksetCellIndex,basis).fastAccessDx(functor_data.dos + offset) = functor_data.seed_value;
604 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
605 KOKKOS_INLINE_FUNCTION
610 for(std::size_t basis=0;basis<functor_data.offsets.extent(0);basis++) {
611 int offset = functor_data.offsets(basis);
612 LO lid = functor_data.lids(worksetCellIndex,offset);
615 functor_data.field(worksetCellIndex,basis).val() = functor_data.x_data(lid,0);
panzer::Traits::Jacobian::ScalarT ScalarT
PHX::View< const int * > offsets
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...
std::string block_id
DEPRECATED - use: getElementBlock()
#define TEUCHOS_ASSERT(assertion_test)
Teuchos::RCP< PHX::DataLayout > functional
<Cell,Basis> or <Cell,Basis>
Kokkos::View< const LO **, Kokkos::LayoutRight, PHX::Device > lids