35 const Teuchos::RCP<const BlockedDOFManager> & indexer,
36 const Teuchos::ParameterList& p)
37 : globalIndexer_(indexer)
38 , useTimeDerivativeSolutionVector_(false)
39 , globalDataKey_(
"Tangent Gather Container")
41 const std::vector<std::string>& names =
42 *(p.get< Teuchos::RCP< std::vector<std::string> > >(
"DOF Names"));
44 indexerNames_ = p.get< Teuchos::RCP< std::vector<std::string> > >(
"Indexer Names");
46 Teuchos::RCP<panzer::PureBasis> basis =
47 p.get< Teuchos::RCP<panzer::PureBasis> >(
"Basis");
50 for (std::size_t fd = 0; fd < names.size(); ++fd) {
52 PHX::MDField<ScalarT,Cell,NODE>(names[fd],basis->functional);
60 if (p.isType<
bool>(
"Use Time Derivative Solution Vector"))
63 if (p.isType<std::string>(
"Global Data Key"))
66 this->setName(
"Gather Tangent");
75 TEUCHOS_ASSERT(gatherFields_.size() == indexerNames_->size());
77 const Workset & workset_0 = (*d.worksets_)[0];
78 const std::string blockId = this->wda(workset_0).
block_id;
80 fieldIds_.resize(gatherFields_.size());
81 fieldOffsets_.resize(gatherFields_.size());
82 fieldGlobalIndexers_.resize(gatherFields_.size());
83 productVectorBlockIndex_.resize(gatherFields_.size());
84 int maxElementBlockGIDCount = -1;
85 for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) {
87 const std::string& fieldName = (*indexerNames_)[fd];
88 const int globalFieldNum = globalIndexer_->getFieldNum(fieldName);
89 productVectorBlockIndex_[fd] = globalIndexer_->getFieldBlock(globalFieldNum);
90 fieldGlobalIndexers_[fd] = globalIndexer_->getFieldDOFManagers()[productVectorBlockIndex_[fd]];
91 fieldIds_[fd] = fieldGlobalIndexers_[fd]->getFieldNum(fieldName);
93 const std::vector<int>&
offsets = fieldGlobalIndexers_[fd]->getGIDFieldOffsets(blockId,fieldIds_[fd]);
94 fieldOffsets_[fd] = PHX::View<int*>(
"GatherSolution_BlockedTpetra(Residual):fieldOffsets",
offsets.size());
95 auto hostFieldOffsets = Kokkos::create_mirror_view(fieldOffsets_[fd]);
96 for(std::size_t i=0; i <
offsets.size(); ++i)
97 hostFieldOffsets(i) =
offsets[i];
98 Kokkos::deep_copy(fieldOffsets_[fd],hostFieldOffsets);
100 maxElementBlockGIDCount = std::max(fieldGlobalIndexers_[fd]->getElementBlockGIDCount(blockId),maxElementBlockGIDCount);
106 worksetLIDs_ = PHX::View<LO**>(
"GatherSolution_BlockedTpetra(Residual):worksetLIDs",
107 gatherFields_[0].extent(0),
108 maxElementBlockGIDCount);
110 indexerNames_ = Teuchos::null;
119 if (d.gedc->containsDataObject(globalDataKey_)) {
120 Teuchos::RCP<GlobalEvaluationData> ged = d.gedc->getDataObject(globalDataKey_);
121 Teuchos::RCP<LOCPair_GlobalEvaluationData> loc_pair =
122 Teuchos::rcp_dynamic_cast<LOCPair_GlobalEvaluationData>(ged);
124 if(loc_pair!=Teuchos::null) {
125 Teuchos::RCP<LinearObjContainer> loc = loc_pair->getGhostedLOC();
126 blockedContainer_ = Teuchos::rcp_dynamic_cast<const ContainerType>(loc,
true);
129 if(blockedContainer_==Teuchos::null) {
130 blockedContainer_ = Teuchos::rcp_dynamic_cast<const ContainerType>(ged,
true);
141 using Teuchos::rcp_dynamic_cast;
147 if (blockedContainer_ == Teuchos::null)
return;
149 const PHX::View<const int*>& localCellIds = this->wda(workset).cell_local_ids_k;
151 RCP<ProductVectorBase<ScalarT>> thyraBlockSolution;
152 if (useTimeDerivativeSolutionVector_)
153 thyraBlockSolution = rcp_dynamic_cast<ProductVectorBase<ScalarT>>(blockedContainer_->get_dxdt(),
true);
155 thyraBlockSolution = rcp_dynamic_cast<ProductVectorBase<ScalarT>>(blockedContainer_->get_x(),
true);
158 int currentWorksetLIDSubBlock = -1;
159 for (std::size_t fieldIndex = 0; fieldIndex < gatherFields_.size(); fieldIndex++) {
161 if (productVectorBlockIndex_[fieldIndex] != currentWorksetLIDSubBlock) {
162 const std::string blockId = this->wda(workset).block_id;
163 const int num_dofs = fieldGlobalIndexers_[fieldIndex]->getElementBlockGIDCount(blockId);
164 fieldGlobalIndexers_[fieldIndex]->getElementLIDs(localCellIds,worksetLIDs_,num_dofs);
165 currentWorksetLIDSubBlock = productVectorBlockIndex_[fieldIndex];
168 const auto& tpetraSolution = *((rcp_dynamic_cast<Thyra::TpetraVector<ScalarT,LO,GO,NodeT>>(thyraBlockSolution->getNonconstVectorBlock(productVectorBlockIndex_[fieldIndex]),
true))->getTpetraVector());
169 const auto& kokkosSolution = tpetraSolution.getLocalViewDevice(Tpetra::Access::ReadOnly);
172 const auto& fieldOffsets = fieldOffsets_[fieldIndex];
173 const auto& worksetLIDs = worksetLIDs_;
174 const auto& fieldValues = gatherFields_[fieldIndex];
176 Kokkos::parallel_for(Kokkos::RangePolicy<PHX::Device>(0,workset.num_cells), KOKKOS_LAMBDA (
const int& cell) {
177 for(
int basis=0; basis < static_cast<int>(fieldOffsets.size()); ++basis) {
178 const int lid = worksetLIDs(cell,fieldOffsets(basis));
179 fieldValues(cell,basis) = kokkosSolution(lid,0);