Panzer Version of the Day
Loading...
Searching...
No Matches
Panzer_GatherTangent_BlockedTpetra_impl.hpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// Panzer: A partial differential equation assembly
4// engine for strongly coupled complex multiphysics systems
5//
6// Copyright 2011 NTESS and the Panzer contributors.
7// SPDX-License-Identifier: BSD-3-Clause
8// *****************************************************************************
9// @HEADER
10
11#ifndef PANZER_GATHER_TANGENT_BLOCKED_TPETRA_IMPL_HPP
12#define PANZER_GATHER_TANGENT_BLOCKED_TPETRA_IMPL_HPP
13
14#include "Teuchos_Assert.hpp"
15#include "Phalanx_DataLayout.hpp"
16
19#include "Panzer_PureBasis.hpp"
20#include "Panzer_TpetraLinearObjFactory.hpp"
24
25#include "Teuchos_FancyOStream.hpp"
26
27#include "Thyra_SpmdVectorBase.hpp"
28#include "Thyra_ProductVectorBase.hpp"
29
30#include "Tpetra_Map.hpp"
31
32template <typename EvalT,typename TRAITS,typename S,typename LO,typename GO,typename NodeT>
35 const Teuchos::RCP<const BlockedDOFManager> & indexer,
36 const Teuchos::ParameterList& p)
37 : globalIndexer_(indexer)
38 , useTimeDerivativeSolutionVector_(false)
39 , globalDataKey_("Tangent Gather Container")
40{
41 const std::vector<std::string>& names =
42 *(p.get< Teuchos::RCP< std::vector<std::string> > >("DOF Names"));
43
44 indexerNames_ = p.get< Teuchos::RCP< std::vector<std::string> > >("Indexer Names");
45
46 Teuchos::RCP<panzer::PureBasis> basis =
47 p.get< Teuchos::RCP<panzer::PureBasis> >("Basis");
48
49 gatherFields_.resize(names.size());
50 for (std::size_t fd = 0; fd < names.size(); ++fd) {
51 gatherFields_[fd] =
52 PHX::MDField<ScalarT,Cell,NODE>(names[fd],basis->functional);
53 this->addEvaluatedField(gatherFields_[fd]);
54 // If blockedContainer_ is null, the evalaution is a no-op. In this
55 // case we need to preserve zero initial value. Do this by not
56 // sharing.
57 this->addUnsharedField(gatherFields_[fd].fieldTag().clone());
58 }
59
60 if (p.isType<bool>("Use Time Derivative Solution Vector"))
61 useTimeDerivativeSolutionVector_ = p.get<bool>("Use Time Derivative Solution Vector");
62
63 if (p.isType<std::string>("Global Data Key"))
64 globalDataKey_ = p.get<std::string>("Global Data Key");
65
66 this->setName("Gather Tangent");
67}
68
69// **********************************************************************
70template <typename EvalT,typename TRAITS,typename S,typename LO,typename GO,typename NodeT>
72postRegistrationSetup(typename TRAITS::SetupData d,
74{
75 TEUCHOS_ASSERT(gatherFields_.size() == indexerNames_->size());
76
77 const Workset & workset_0 = (*d.worksets_)[0];
78 const std::string blockId = this->wda(workset_0).block_id;
79
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) {
86 // get field ID from DOF manager
87 const std::string& fieldName = (*indexerNames_)[fd];
88 const int globalFieldNum = globalIndexer_->getFieldNum(fieldName); // Field number in the aggregate BlockDOFManager
89 productVectorBlockIndex_[fd] = globalIndexer_->getFieldBlock(globalFieldNum);
90 fieldGlobalIndexers_[fd] = globalIndexer_->getFieldDOFManagers()[productVectorBlockIndex_[fd]];
91 fieldIds_[fd] = fieldGlobalIndexers_[fd]->getFieldNum(fieldName); // Field number in the sub-global-indexer
92
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);
99
100 maxElementBlockGIDCount = std::max(fieldGlobalIndexers_[fd]->getElementBlockGIDCount(blockId),maxElementBlockGIDCount);
101 }
102
103 // We will use one workset lid view for all fields, but has to be
104 // sized big enough to hold the largest elementBlockGIDCount in the
105 // ProductVector.
106 worksetLIDs_ = PHX::View<LO**>("GatherSolution_BlockedTpetra(Residual):worksetLIDs",
107 gatherFields_[0].extent(0),
108 maxElementBlockGIDCount);
109
110 indexerNames_ = Teuchos::null; // Don't need this anymore
111}
112
113// **********************************************************************
114template <typename EvalT,typename TRAITS,typename S,typename LO,typename GO,typename NodeT>
116preEvaluate(typename TRAITS::PreEvalData d)
117{
118 // try to extract linear object container
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);
123
124 if(loc_pair!=Teuchos::null) {
125 Teuchos::RCP<LinearObjContainer> loc = loc_pair->getGhostedLOC();
126 blockedContainer_ = Teuchos::rcp_dynamic_cast<const ContainerType>(loc,true);
127 }
128
129 if(blockedContainer_==Teuchos::null) {
130 blockedContainer_ = Teuchos::rcp_dynamic_cast<const ContainerType>(ged,true);
131 }
132 }
133}
134
135// **********************************************************************
136template <typename EvalT,typename TRAITS,typename S,typename LO,typename GO,typename NodeT>
138evaluateFields(typename TRAITS::EvalData workset)
139{
140 using Teuchos::RCP;
141 using Teuchos::rcp_dynamic_cast;
142 using Thyra::VectorBase;
144
145 // If blockedContainer_ was not initialized, then no global evaluation data
146 // container was set, in which case this evaluator becomes a no-op
147 if (blockedContainer_ == Teuchos::null) return;
148
149 const PHX::View<const int*>& localCellIds = this->wda(workset).cell_local_ids_k;
150
151 RCP<ProductVectorBase<ScalarT>> thyraBlockSolution;
152 if (useTimeDerivativeSolutionVector_)
153 thyraBlockSolution = rcp_dynamic_cast<ProductVectorBase<ScalarT>>(blockedContainer_->get_dxdt(),true);
154 else
155 thyraBlockSolution = rcp_dynamic_cast<ProductVectorBase<ScalarT>>(blockedContainer_->get_x(),true);
156
157 // Loop over gathered fields
158 int currentWorksetLIDSubBlock = -1;
159 for (std::size_t fieldIndex = 0; fieldIndex < gatherFields_.size(); fieldIndex++) {
160 // workset LIDs only change for different sub blocks
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];
166 }
167
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);
170
171 // Class data fields for lambda capture
172 const auto& fieldOffsets = fieldOffsets_[fieldIndex];
173 const auto& worksetLIDs = worksetLIDs_;
174 const auto& fieldValues = gatherFields_[fieldIndex];
175
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);
180 }
181 });
182 }
183
184}
185
186// **********************************************************************
187
188#endif
PHX::View< const int * > offsets
std::vector< PHX::MDField< ScalarT, Cell, NODE > > gatherFields_
Teuchos::RCP< std::vector< std::string > > indexerNames_
void postRegistrationSetup(typename TRAITS::SetupData d, PHX::FieldManager< TRAITS > &vm)
virtual Teuchos::RCP< CloneableEvaluator > clone(const Teuchos::ParameterList &pl) const
std::string block_id
DEPRECATED - use: getElementBlock()