37 const Teuchos::RCP<const BlockedDOFManager> & indexer,
38 const Teuchos::ParameterList& p)
39 : globalIndexer_(indexer)
40 , useTimeDerivativeSolutionVector_(false)
41 , globalDataKey_(
"Tangent Gather Container")
43 const std::vector<std::string>& names =
44 *(p.get< Teuchos::RCP< std::vector<std::string> > >(
"DOF Names"));
46 indexerNames_ = p.get< Teuchos::RCP< std::vector<std::string> > >(
"Indexer Names");
48 Teuchos::RCP<panzer::PureBasis> basis =
49 p.get< Teuchos::RCP<panzer::PureBasis> >(
"Basis");
52 for (std::size_t fd = 0; fd < names.size(); ++fd) {
54 PHX::MDField<ScalarT,Cell,NODE>(names[fd],basis->functional);
62 if (p.isType<
bool>(
"Use Time Derivative Solution Vector"))
65 if (p.isType<std::string>(
"Global Data Key"))
68 this->setName(
"Gather Tangent");
77 TEUCHOS_ASSERT(gatherFields_.size() == indexerNames_->size());
79 const Workset & workset_0 = (*d.worksets_)[0];
80 const std::string blockId = this->wda(workset_0).
block_id;
82 fieldIds_.resize(gatherFields_.size());
83 fieldOffsets_.resize(gatherFields_.size());
84 fieldGlobalIndexers_.resize(gatherFields_.size());
85 productVectorBlockIndex_.resize(gatherFields_.size());
86 int maxElementBlockGIDCount = -1;
87 for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) {
89 const std::string& fieldName = (*indexerNames_)[fd];
90 const int globalFieldNum = globalIndexer_->getFieldNum(fieldName);
91 productVectorBlockIndex_[fd] = globalIndexer_->getFieldBlock(globalFieldNum);
92 fieldGlobalIndexers_[fd] = globalIndexer_->getFieldDOFManagers()[productVectorBlockIndex_[fd]];
93 fieldIds_[fd] = fieldGlobalIndexers_[fd]->getFieldNum(fieldName);
95 const std::vector<int>&
offsets = fieldGlobalIndexers_[fd]->getGIDFieldOffsets(blockId,fieldIds_[fd]);
96 fieldOffsets_[fd] = PHX::View<int*>(
"GatherSolution_BlockedTpetra(Residual):fieldOffsets",
offsets.size());
97 auto hostFieldOffsets = Kokkos::create_mirror_view(fieldOffsets_[fd]);
98 for(std::size_t i=0; i <
offsets.size(); ++i)
99 hostFieldOffsets(i) =
offsets[i];
100 Kokkos::deep_copy(fieldOffsets_[fd],hostFieldOffsets);
102 maxElementBlockGIDCount = std::max(fieldGlobalIndexers_[fd]->getElementBlockGIDCount(blockId),maxElementBlockGIDCount);
108 worksetLIDs_ = PHX::View<LO**>(
"GatherSolution_BlockedTpetra(Residual):worksetLIDs",
109 gatherFields_[0].extent(0),
110 maxElementBlockGIDCount);
112 indexerNames_ = Teuchos::null;
121 using Teuchos::rcp_dynamic_cast;
124 if (!d.gedc->containsDataObject(globalDataKey_))
127 RCP<GlobalEvaluationData> ged = d.gedc->getDataObject(globalDataKey_);
131 RCP<const ContainerType> blockedContainer = rcp_dynamic_cast<const ContainerType>(ged);
132 RCP<LOCPair_GlobalEvaluationData> loc_pair =
133 rcp_dynamic_cast<LOCPair_GlobalEvaluationData>(ged);
135 if(loc_pair!=Teuchos::null)
136 blockedContainer = rcp_dynamic_cast<const ContainerType>(loc_pair->getGhostedLOC(),
true);
138 if(blockedContainer!=Teuchos::null) {
139 blockedContainer_ = blockedContainer;
146 xBvRoGed_ = rcp_dynamic_cast<BVROGED>(ged,
true);
155 using Teuchos::rcp_dynamic_cast;
161 if (blockedContainer_ == Teuchos::null && xBvRoGed_ == Teuchos::null)
return;
163 const PHX::View<const int*>& localCellIds = this->wda(workset).cell_local_ids_k;
165 RCP<ProductVectorBase<ScalarT>> thyraBlockSolution;
166 if (blockedContainer_ != Teuchos::null) {
167 if (useTimeDerivativeSolutionVector_)
168 thyraBlockSolution = rcp_dynamic_cast<ProductVectorBase<ScalarT>>(blockedContainer_->get_dxdt(),
true);
170 thyraBlockSolution = rcp_dynamic_cast<ProductVectorBase<ScalarT>>(blockedContainer_->get_x(),
true);
174 int currentWorksetLIDSubBlock = -1;
175 for (std::size_t fieldIndex = 0; fieldIndex < gatherFields_.size(); fieldIndex++) {
177 if (productVectorBlockIndex_[fieldIndex] != currentWorksetLIDSubBlock) {
178 const std::string blockId = this->wda(workset).block_id;
179 const int num_dofs = fieldGlobalIndexers_[fieldIndex]->getElementBlockGIDCount(blockId);
180 fieldGlobalIndexers_[fieldIndex]->getElementLIDs(localCellIds,worksetLIDs_,num_dofs);
181 currentWorksetLIDSubBlock = productVectorBlockIndex_[fieldIndex];
185 const int blockIndex = productVectorBlockIndex_[fieldIndex];
186 RCP<const VectorType> tpetraSolution;
187 if (thyraBlockSolution != Teuchos::null) {
188 tpetraSolution = rcp_dynamic_cast<Thyra::TpetraVector<ScalarT,LO,GO,NodeT>>(
189 thyraBlockSolution->getNonconstVectorBlock(blockIndex),
true)->getConstTpetraVector();
193 tpetraSolution = rcp_dynamic_cast<TVROGED>(xBvRoGed_->getGEDBlock(blockIndex),
true)
196 const auto& kokkosSolution = tpetraSolution->getLocalViewDevice(Tpetra::Access::ReadOnly);
199 const auto& fieldOffsets = fieldOffsets_[fieldIndex];
200 const auto& worksetLIDs = worksetLIDs_;
201 const auto& fieldValues = gatherFields_[fieldIndex];
203 Kokkos::parallel_for(Kokkos::RangePolicy<PHX::Device>(0,workset.num_cells), KOKKOS_LAMBDA (
const int& cell) {
204 for(
int basis=0; basis < static_cast<int>(fieldOffsets.size()); ++basis) {
205 const int lid = worksetLIDs(cell,fieldOffsets(basis));
206 fieldValues(cell,basis) = kokkosSolution(lid,0);