43 #ifndef PANZER_GATHER_SOLUTION_TPETRA_IMPL_HPP
44 #define PANZER_GATHER_SOLUTION_TPETRA_IMPL_HPP
46 #include "Teuchos_Assert.hpp"
47 #include "Phalanx_DataLayout.hpp"
57 #include "Teuchos_FancyOStream.hpp"
59 #include "Tpetra_Vector.hpp"
60 #include "Tpetra_Map.hpp"
66 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
71 : globalIndexer_(indexer)
72 , has_tangent_fields_(false)
74 typedef std::vector< std::vector<std::string> > vvstring;
79 const std::vector<std::string> & names = input.
getDofNames();
88 gatherFields_.resize(names.size());
89 for (std::size_t fd = 0; fd < names.size(); ++fd) {
91 PHX::MDField<ScalarT,Cell,NODE>(names[fd],basis->
functional);
92 this->addEvaluatedField(gatherFields_[fd]);
96 if (tangent_field_names.size()>0) {
97 TEUCHOS_ASSERT(gatherFields_.size() == tangent_field_names.size());
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]);
112 std::string firstName =
"<none>";
114 firstName = names[0];
116 std::string n =
"GatherSolution (Tpetra): "+firstName+
" (Residual)";
121 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
128 fieldIds_.resize(gatherFields_.size());
130 const Workset & workset_0 = (*d.worksets_)[0];
131 std::string blockId = this->wda(workset_0).
block_id;
132 scratch_offsets_.resize(gatherFields_.size());
134 for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) {
135 const std::string& fieldName = indexerNames_[fd];
136 fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
138 int fieldNum = fieldIds_[fd];
139 const std::vector<int> &
offsets = globalIndexer_->getGIDFieldOffsets(blockId,fieldNum);
140 scratch_offsets_[fd] = Kokkos::View<int*,PHX::Device>(
"offsets",offsets.size());
141 for(std::size_t i=0;i<offsets.size();i++)
142 scratch_offsets_[fd](i) = offsets[i];
145 scratch_lids_ = Kokkos::View<LO**,PHX::Device>(
"lids",gatherFields_[0].extent(0),
146 globalIndexer_->getElementBlockGIDCount(blockId));
148 indexerNames_.clear();
152 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
159 tpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(d.gedc->getDataObject(globalDataKey_));
161 if(tpetraContainer_==Teuchos::null) {
164 tpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(loc);
169 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
176 std::string blockId = this->wda(workset).block_id;
177 const std::vector<std::size_t> & localCellIds = this->wda(workset).cell_local_ids;
180 if (useTimeDerivativeSolutionVector_)
181 x = tpetraContainer_->get_dxdt();
183 x = tpetraContainer_->get_x();
185 auto x_data = x->template getLocalView<PHX::Device>();
187 globalIndexer_->getElementLIDs(this->wda(workset).cell_local_ids_k,scratch_lids_);
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];
201 Kokkos::parallel_for(localCellIds.size(), KOKKOS_LAMBDA (std::size_t worksetCellIndex) {
203 for(std::size_t basis=0;basis<
offsets.extent(0);basis++) {
205 LO lid =
lids(worksetCellIndex,offset);
208 gather_field(worksetCellIndex,basis) = x_data(lid,0);
218 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
223 : globalIndexer_(indexer)
224 , has_tangent_fields_(false)
226 typedef std::vector< std::vector<std::string> > vvstring;
231 const std::vector<std::string> & names = input.
getDofNames();
240 gatherFields_.resize(names.size());
241 for (std::size_t fd = 0; fd < names.size(); ++fd) {
243 PHX::MDField<ScalarT,Cell,NODE>(names[fd],basis->
functional);
244 this->addEvaluatedField(gatherFields_[fd]);
247 this->addUnsharedField(gatherFields_[fd].fieldTag().clone());
251 if (tangent_field_names.size()>0) {
252 TEUCHOS_ASSERT(gatherFields_.size() == tangent_field_names.size());
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]);
267 std::string firstName =
"<none>";
269 firstName = names[0];
271 std::string n =
"GatherSolution (Tpetra): "+firstName+
" (Tangent)";
276 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
283 fieldIds_.resize(gatherFields_.size());
285 for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) {
286 const std::string& fieldName = indexerNames_[fd];
287 fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
290 indexerNames_.clear();
294 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
301 tpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(d.gedc->getDataObject(globalDataKey_));
303 if(tpetraContainer_==Teuchos::null) {
306 tpetraContainer_ = Teuchos::rcp_dynamic_cast<LOC>(loc);
311 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
318 std::string blockId = this->wda(workset).block_id;
319 const std::vector<std::size_t> & localCellIds = this->wda(workset).cell_local_ids;
322 if (useTimeDerivativeSolutionVector_)
323 x = tpetraContainer_->get_dxdt();
325 x = tpetraContainer_->get_x();
334 typedef typename PHX::MDField<ScalarT,Cell,NODE>::array_type::reference_type reference_type;
336 if (has_tangent_fields_) {
338 for(std::size_t worksetCellIndex=0;worksetCellIndex<localCellIds.size();++worksetCellIndex) {
339 std::size_t cellLocalId = localCellIds[worksetCellIndex];
341 auto LIDs = globalIndexer_->getElementLIDs(cellLocalId);
344 for (std::size_t fieldIndex=0; fieldIndex<gatherFields_.size();fieldIndex++) {
345 int fieldNum = fieldIds_[fieldIndex];
346 const std::vector<int> & elmtOffset = globalIndexer_->getGIDFieldOffsets(blockId,fieldNum);
348 const std::vector< PHX::MDField<const RealT,Cell,NODE> >& tf_ref =
349 tangentFields_[fieldIndex];
350 const std::size_t num_tf = tf_ref.size();
353 for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
354 int offset = elmtOffset[basis];
355 LO lid = LIDs[offset];
356 reference_type gf_ref = (gatherFields_[fieldIndex])(worksetCellIndex,basis);
357 gf_ref.val() = x_array[lid];
358 for (std::size_t i=0; i<num_tf; ++i)
359 gf_ref.fastAccessDx(i) = tf_ref[i](worksetCellIndex,basis);
366 for(std::size_t worksetCellIndex=0;worksetCellIndex<localCellIds.size();++worksetCellIndex) {
367 std::size_t cellLocalId = localCellIds[worksetCellIndex];
369 auto LIDs = globalIndexer_->getElementLIDs(cellLocalId);
372 for (std::size_t fieldIndex=0; fieldIndex<gatherFields_.size();fieldIndex++) {
373 int fieldNum = fieldIds_[fieldIndex];
374 const std::vector<int> & elmtOffset = globalIndexer_->getGIDFieldOffsets(blockId,fieldNum);
377 for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
378 int offset = elmtOffset[basis];
379 LO lid = LIDs[offset];
380 reference_type gf_ref = (gatherFields_[fieldIndex])(worksetCellIndex,basis);
381 gf_ref.val() = x_array[lid];
392 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
397 : globalIndexer_(indexer)
404 const std::vector<std::string> & names = input.
getDofNames();
416 gatherFields_.resize(names.size());
417 scratch_offsets_.resize(names.size());
418 for (std::size_t fd = 0; fd < names.size(); ++fd) {
419 PHX::MDField<ScalarT,Cell,NODE> f(names[fd],basis->
functional);
420 gatherFields_[fd] = f;
421 this->addEvaluatedField(gatherFields_[fd]);
424 this->addUnsharedField(gatherFields_[fd].fieldTag().clone());
428 std::string firstName =
"<none>";
430 firstName = names[0];
433 if(disableSensitivities_) {
434 std::string n =
"GatherSolution (Tpetra, No Sensitivities): "+firstName+
" (Jacobian)";
438 std::string n =
"GatherSolution (Tpetra): "+firstName+
" ("+PHX::print<EvalT>()+
") ";
444 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
451 fieldIds_.resize(gatherFields_.size());
453 const Workset & workset_0 = (*d.worksets_)[0];
454 std::string blockId = this->wda(workset_0).
block_id;
456 for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) {
458 const std::string& fieldName = indexerNames_[fd];
459 fieldIds_[fd] = globalIndexer_->getFieldNum(fieldName);
461 int fieldNum = fieldIds_[fd];
462 const std::vector<int> &
offsets = globalIndexer_->getGIDFieldOffsets(blockId,fieldNum);
463 scratch_offsets_[fd] = Kokkos::View<int*,PHX::Device>(
"offsets",offsets.size());
464 for(std::size_t i=0;i<offsets.size();i++)
465 scratch_offsets_[fd](i) = offsets[i];
468 scratch_lids_ = Kokkos::View<LO**,PHX::Device>(
"lids",gatherFields_[0].extent(0),
469 globalIndexer_->getElementBlockGIDCount(blockId));
471 indexerNames_.clear();
475 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
481 using Teuchos::rcp_dynamic_cast;
488 if(!disableSensitivities_) {
489 if(d.first_sensitivities_name==sensitivitiesName_)
490 applySensitivities_ =
true;
492 applySensitivities_ =
false;
495 applySensitivities_ =
false;
502 std::string post = useTimeDerivativeSolutionVector_ ?
" - Xdot" :
" - X";
503 if(d.gedc->containsDataObject(globalDataKey_+post)) {
504 ged = d.gedc->getDataObject(globalDataKey_+post);
506 RCP<RO_GED> ro_ged = rcp_dynamic_cast<RO_GED>(ged,
true);
508 x_vector = ro_ged->getGhostedVector_Tpetra();
510 x_vector->template sync<PHX::Device>();
515 ged = d.gedc->getDataObject(globalDataKey_);
519 RCP<LOC> tpetraContainer = rcp_dynamic_cast<LOC>(ged);
522 if(loc_pair!=Teuchos::null) {
525 tpetraContainer = rcp_dynamic_cast<LOC>(loc);
528 if(tpetraContainer!=Teuchos::null) {
529 if (useTimeDerivativeSolutionVector_)
530 x_vector = tpetraContainer->get_dxdt();
532 x_vector = tpetraContainer->get_x();
534 x_vector->template sync<PHX::Device>();
542 RCP<RO_GED> ro_ged = rcp_dynamic_cast<RO_GED>(ged,
true);
544 x_vector = ro_ged->getGhostedVector_Tpetra();
547 x_vector->template sync<PHX::Device>();
551 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
556 std::string blockId = this->wda(workset).block_id;
558 double seed_value = 0.0;
559 if (useTimeDerivativeSolutionVector_) {
560 seed_value = workset.alpha;
562 else if (gatherSeedIndex_<0) {
563 seed_value = workset.beta;
565 else if(!useTimeDerivativeSolutionVector_) {
566 seed_value = workset.gather_seeds[gatherSeedIndex_];
575 if(!applySensitivities_)
579 bool use_seed =
true;
583 globalIndexer_->getElementLIDs(this->wda(workset).cell_local_ids_k,scratch_lids_);
588 functor_data.x_data = x_vector->template getLocalView<PHX::Device>();
589 functor_data.seed_value = seed_value;
590 functor_data.lids = scratch_lids_;
593 for(std::size_t fieldIndex=0;
594 fieldIndex<gatherFields_.size();fieldIndex++) {
597 functor_data.offsets = scratch_offsets_[fieldIndex];
598 functor_data.field = gatherFields_[fieldIndex];
601 Kokkos::parallel_for(workset.num_cells,*
this);
603 Kokkos::parallel_for(Kokkos::RangePolicy<PHX::Device,NoSeed>(0,workset.num_cells),*
this);
608 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
609 KOKKOS_INLINE_FUNCTION
614 for(std::size_t basis=0;basis<functor_data.offsets.extent(0);basis++) {
615 int offset = functor_data.offsets(basis);
616 LO lid = functor_data.lids(worksetCellIndex,offset);
619 functor_data.field(worksetCellIndex,basis).val() = functor_data.x_data(lid,0);
620 functor_data.field(worksetCellIndex,basis).fastAccessDx(offset) = functor_data.seed_value;
625 template<
typename TRAITS,
typename LO,
typename GO,
typename NodeT>
626 KOKKOS_INLINE_FUNCTION
631 for(std::size_t basis=0;basis<functor_data.offsets.extent(0);basis++) {
632 int offset = functor_data.offsets(basis);
633 LO lid = functor_data.lids(worksetCellIndex,offset);
636 functor_data.field(worksetCellIndex,basis).val() = functor_data.x_data(lid,0);
Kokkos::View< const LO **, PHX::Device > lids
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...
#define TEUCHOS_ASSERT(assertion_test)
Teuchos::RCP< PHX::DataLayout > functional
<Cell,Basis> or <Cell,Basis>
Kokkos::View< const int *, PHX::Device > offsets