11 #ifndef PANZER_GATHER_TANGENT_BLOCKED_TPETRA_IMPL_HPP
12 #define PANZER_GATHER_TANGENT_BLOCKED_TPETRA_IMPL_HPP
14 #include "Teuchos_Assert.hpp"
15 #include "Phalanx_DataLayout.hpp"
20 #include "Panzer_TpetraLinearObjFactory.hpp"
25 #include "Teuchos_FancyOStream.hpp"
27 #include "Thyra_SpmdVectorBase.hpp"
28 #include "Thyra_ProductVectorBase.hpp"
30 #include "Tpetra_Map.hpp"
32 template <
typename EvalT,
typename TRAITS,
typename S,
typename LO,
typename GO,
typename NodeT>
37 : globalIndexer_(indexer)
38 , useTimeDerivativeSolutionVector_(false)
39 , globalDataKey_(
"Tangent Gather Container")
41 const std::vector<std::string>& names =
50 for (std::size_t fd = 0; fd < names.size(); ++fd) {
60 if (p.
isType<
bool>(
"Use Time Derivative Solution Vector"))
63 if (p.
isType<std::string>(
"Global Data Key"))
66 this->setName(
"Gather Tangent");
70 template <
typename EvalT,
typename TRAITS,
typename S,
typename LO,
typename GO,
typename NodeT>
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;
114 template <
typename EvalT,
typename TRAITS,
typename S,
typename LO,
typename GO,
typename NodeT>
119 if (d.gedc->containsDataObject(globalDataKey_)) {
124 if(loc_pair!=Teuchos::null) {
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);
136 template <
typename EvalT,
typename TRAITS,
typename S,
typename LO,
typename GO,
typename NodeT>
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;
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);
Teuchos::RCP< std::vector< std::string > > indexerNames_
virtual Teuchos::RCP< CloneableEvaluator > clone(const Teuchos::ParameterList &pl) const
GatherTangent_BlockedTpetra()
T & get(const std::string &name, T def_value)
void postRegistrationSetup(typename TRAITS::SetupData d, PHX::FieldManager< TRAITS > &vm)
Teuchos::RCP< LinearObjContainer > getGhostedLOC() const
PHX::View< const int * > offsets
bool useTimeDerivativeSolutionVector_
std::string globalDataKey_
void evaluateFields(typename TRAITS::EvalData d)
std::string block_id
DEPRECATED - use: getElementBlock()
std::vector< PHX::MDField< ScalarT, Cell, NODE > > gatherFields_
void preEvaluate(typename TRAITS::PreEvalData d)
bool isType(const std::string &name) const
#define TEUCHOS_ASSERT(assertion_test)