11#ifndef PANZER_GATHER_SOLUTION_BLOCKED_TPETRA_IMPL_HPP
12#define PANZER_GATHER_SOLUTION_BLOCKED_TPETRA_IMPL_HPP
14#include "Teuchos_Assert.hpp"
15#include "Phalanx_DataLayout.hpp"
20#include "Panzer_TpetraLinearObjFactory.hpp"
27#include "Teuchos_FancyOStream.hpp"
29#include "Thyra_SpmdVectorBase.hpp"
30#include "Thyra_ProductVectorBase.hpp"
32#include "Tpetra_Map.hpp"
34template <
typename EvalT,
typename TRAITS,
typename S,
typename LO,
typename GO,
typename NodeT>
37 const Teuchos::RCP<const BlockedDOFManager> & indexer,
38 const Teuchos::ParameterList& p)
40 const std::vector<std::string>& names =
41 *(p.get< Teuchos::RCP< std::vector<std::string> > >(
"DOF Names"));
43 Teuchos::RCP<panzer::PureBasis> basis =
44 p.get< Teuchos::RCP<panzer::PureBasis> >(
"Basis");
46 for (std::size_t fd = 0; fd < names.size(); ++fd) {
47 PHX::MDField<ScalarT,Cell,NODE> field = PHX::MDField<ScalarT,Cell,NODE>(names[fd],basis->functional);
48 this->addEvaluatedField(field.fieldTag());
51 this->setName(
"Gather Solution");
58template <
typename TRAITS,
typename S,
typename LO,
typename GO,
typename NodeT>
61 const Teuchos::RCP<const BlockedDOFManager> & indexer,
62 const Teuchos::ParameterList& p)
66 typedef std::vector< std::vector<std::string> > vvstring;
71 const std::vector<std::string> & names = input.
getDofNames();
72 Teuchos::RCP<const panzer::PureBasis> basis = input.
getBasis();
81 for (std::size_t fd = 0; fd < names.size(); ++fd) {
83 PHX::MDField<ScalarT,Cell,NODE>(names[fd],basis->functional);
88 if (tangent_field_names.size()>0) {
89 TEUCHOS_ASSERT(gatherFields_.size() == tangent_field_names.size());
91 has_tangent_fields_ = true;
92 tangentFields_.resize(gatherFields_.size());
93 for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) {
94 tangentFields_[fd].resize(tangent_field_names[fd].size());
95 for (std::size_t i=0; i<tangent_field_names[fd].size(); ++i) {
96 tangentFields_[fd][i] =
97 PHX::MDField<const ScalarT,Cell,NODE>(tangent_field_names[fd][i],basis->functional);
98 this->addDependentField(tangentFields_[fd][i]);
104 std::string firstName =
"<none>";
106 firstName = names[0];
108 std::string n =
"GatherSolution (BlockedTpetra): "+firstName+
" (Residual)";
113template <
typename TRAITS,
typename S,
typename LO,
typename GO,
typename NodeT>
120 const Workset & workset_0 = (*d.worksets_)[0];
121 const std::string blockId = this->
wda(workset_0).block_id;
127 int maxElementBlockGIDCount = -1;
131 const int globalFieldNum =
globalIndexer_->getFieldNum(fieldName);
137 fieldOffsets_[fd] = PHX::View<int*>(
"GatherSolution_BlockedTpetra(Residual):fieldOffsets",offsets.size());
138 auto hostFieldOffsets = Kokkos::create_mirror_view(
fieldOffsets_[fd]);
139 for(std::size_t i=0; i < offsets.size(); ++i)
140 hostFieldOffsets(i) = offsets[i];
143 maxElementBlockGIDCount = std::max(
fieldGlobalIndexers_[fd]->getElementBlockGIDCount(blockId),maxElementBlockGIDCount);
149 worksetLIDs_ = PHX::View<LO**>(
"GatherSolution_BlockedTpetra(Residual):worksetLIDs",
151 maxElementBlockGIDCount);
157template <
typename TRAITS,
typename S,
typename LO,
typename GO,
typename NodeT>
166template <
typename TRAITS,
typename S,
typename LO,
typename GO,
typename NodeT>
171 using Teuchos::rcp_dynamic_cast;
175 const PHX::View<const int*>& localCellIds = this->
wda(workset).cell_local_ids_k;
177 RCP<ProductVectorBase<ScalarT>> thyraBlockSolution;
179 thyraBlockSolution = rcp_dynamic_cast<ProductVectorBase<ScalarT>>(
blockedContainer_->get_dxdt(),
true);
181 thyraBlockSolution = rcp_dynamic_cast<ProductVectorBase<ScalarT>>(
blockedContainer_->get_x(),
true);
184 int currentWorksetLIDSubBlock = -1;
185 for (std::size_t fieldIndex = 0; fieldIndex <
gatherFields_.size(); fieldIndex++) {
188 const std::string blockId = this->
wda(workset).block_id;
194 const auto& tpetraSolution = *((rcp_dynamic_cast<Thyra::TpetraVector<ScalarT,LO,GO,NodeT>>(thyraBlockSolution->getNonconstVectorBlock(
productVectorBlockIndex_[fieldIndex]),
true))->getTpetraVector());
195 const auto& kokkosSolution = tpetraSolution.getLocalViewDevice(Tpetra::Access::ReadOnly);
202 Kokkos::parallel_for(Kokkos::RangePolicy<PHX::ExecutionSpace>(0,workset.num_cells), KOKKOS_LAMBDA (
const int& cell) {
203 for(
int basis=0; basis < static_cast<int>(fieldOffsets.size()); ++basis) {
204 const int lid = worksetLIDs(cell,fieldOffsets(basis));
205 fieldValues(cell,basis) = kokkosSolution(lid,0);
216template <
typename TRAITS,
typename S,
typename LO,
typename GO,
typename NodeT>
219 const Teuchos::RCP<const BlockedDOFManager> & indexer,
220 const Teuchos::ParameterList& p)
224 typedef std::vector< std::vector<std::string> > vvstring;
229 const std::vector<std::string> & names = input.
getDofNames();
230 Teuchos::RCP<const panzer::PureBasis> basis = input.
getBasis();
239 for (std::size_t fd = 0; fd < names.size(); ++fd) {
241 PHX::MDField<ScalarT,Cell,NODE>(names[fd],basis->functional);
246 if (tangent_field_names.size()>0) {
247 TEUCHOS_ASSERT(gatherFields_.size() == tangent_field_names.size());
249 has_tangent_fields_ = true;
250 tangentFields_.resize(gatherFields_.size());
251 for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) {
252 tangentFields_[fd].resize(tangent_field_names[fd].size());
253 for (std::size_t i=0; i<tangent_field_names[fd].size(); ++i) {
254 tangentFields_[fd][i] =
255 PHX::MDField<const RealT,Cell,NODE>(tangent_field_names[fd][i],basis->functional);
256 this->addDependentField(tangentFields_[fd][i]);
262 std::string firstName =
"<none>";
264 firstName = names[0];
266 std::string n =
"GatherSolution (BlockedTpetra): "+firstName+
" (Tangent)";
271template <
typename TRAITS,
typename S,
typename LO,
typename GO,
typename NodeT>
278 const Workset & workset_0 = (*d.worksets_)[0];
279 const std::string blockId = this->
wda(workset_0).block_id;
284 int maxElementBlockGIDCount = -1;
288 const int globalFieldNum =
globalIndexer_->getFieldNum(fieldName);
291 fieldIds_[fd] = subGlobalIndexer->getFieldNum(fieldName);
293 const std::vector<int>& offsets = subGlobalIndexer->getGIDFieldOffsets(blockId,
fieldIds_[fd]);
294 fieldOffsets_[fd] = PHX::View<int*>(
"GatherSolution_BlockedTpetra(Tangent):fieldOffsets",offsets.size());
295 auto hostOffsets = Kokkos::create_mirror_view(
fieldOffsets_[fd]);
296 for (std::size_t i=0; i < offsets.size(); ++i)
297 hostOffsets(i) = offsets[i];
299 maxElementBlockGIDCount = std::max(subGlobalIndexer->getElementBlockGIDCount(blockId),maxElementBlockGIDCount);
305 worksetLIDs_ = PHX::View<LO**>(
"ScatterResidual_BlockedTpetra(Tangent):worksetLIDs",
307 maxElementBlockGIDCount);
312 size_t inner_vector_max_size = 0;
314 inner_vector_max_size = std::max(inner_vector_max_size,
tangentFields_[fd].size());
330template <
typename TRAITS,
typename S,
typename LO,
typename GO,
typename NodeT>
339template <
typename TRAITS,
typename S,
typename LO,
typename GO,
typename NodeT>
344 using Teuchos::ArrayRCP;
345 using Teuchos::ptrFromRef;
346 using Teuchos::rcp_dynamic_cast;
349 using Thyra::SpmdVectorBase;
352 Teuchos::FancyOStream out(Teuchos::rcpFromRef(std::cout));
353 out.setShowProcRank(
true);
354 out.setOutputToRootOnly(-1);
356 const PHX::View<const int*> & localCellIds = this->
wda(workset).getLocalCellIDs();
358 Teuchos::RCP<ProductVectorBase<double> > blockedSolution;
360 blockedSolution = rcp_dynamic_cast<ProductVectorBase<double> >(
blockedContainer_->get_dxdt());
362 blockedSolution = rcp_dynamic_cast<ProductVectorBase<double> >(
blockedContainer_->get_x());
365 int currentWorksetLIDSubBlock = -1;
366 for (std::size_t fieldIndex = 0; fieldIndex <
gatherFields_.size(); fieldIndex++) {
370 const std::string blockId = this->
wda(workset).block_id;
372 blockIndexer->getElementLIDs(localCellIds,
worksetLIDs_,num_dofs);
377 const auto& subblockSolution = *((rcp_dynamic_cast<Thyra::TpetraVector<RealT,LO,GO,NodeT>>(blockedSolution->getNonconstVectorBlock(blockRowIndex),
true))->getTpetraVector());
378 const auto kokkosSolution = subblockSolution.getLocalViewDevice(Tpetra::Access::ReadOnly);
381 const PHX::View<const int*> fieldOffsets =
fieldOffsets_[fieldIndex];
383 const PHX::View<ScalarT**> fieldValues =
gatherFields_[fieldIndex].get_static_view();
388 const auto kokkosTangents = Kokkos::subview(tangentFieldsDevice,fieldIndex,Kokkos::ALL());
389 Kokkos::parallel_for(Kokkos::RangePolicy<PHX::ExecutionSpace>(0,workset.num_cells), KOKKOS_LAMBDA (
const int& cell) {
390 for (
int basis=0; basis < static_cast<int>(fieldOffsets.size()); ++basis) {
391 const int rowLID = worksetLIDs(cell,fieldOffsets(basis));
392 fieldValues(cell,basis).zero();
393 fieldValues(cell,basis).val() = kokkosSolution(rowLID,0);
394 for (
int i_tangent=0; i_tangent<numTangents; ++i_tangent)
395 fieldValues(cell,basis).fastAccessDx(i_tangent) = kokkosTangents(i_tangent)(cell,basis);
399 Kokkos::parallel_for(Kokkos::RangePolicy<PHX::ExecutionSpace>(0,workset.num_cells), KOKKOS_LAMBDA (
const int& cell) {
400 for (
int basis=0; basis < static_cast<int>(fieldOffsets.size()); ++basis) {
401 const int rowLID = worksetLIDs(cell,fieldOffsets(basis));
402 fieldValues(cell,basis).zero();
403 fieldValues(cell,basis) = kokkosSolution(rowLID,0);
415template <
typename TRAITS,
typename S,
typename LO,
typename GO,
typename NodeT>
418 const Teuchos::RCP<const BlockedDOFManager> & indexer,
419 const Teuchos::ParameterList& p)
425 const std::vector<std::string> & names = input.
getDofNames();
426 Teuchos::RCP<const panzer::PureBasis> basis = input.
getBasis();
435 for (std::size_t fd = 0; fd < names.size(); ++fd) {
436 PHX::MDField<ScalarT,Cell,NODE> f(names[fd],basis->functional);
442 std::string firstName =
"<none>";
444 firstName = names[0];
448 std::string n =
"GatherSolution (BlockedTpetra, No Sensitivities): "+firstName+
" (Jacobian)";
452 std::string n =
"GatherSolution (BlockedTpetra): "+firstName+
" ("+PHX::print<EvalT>()+
") ";
458template <
typename TRAITS,
typename S,
typename LO,
typename GO,
typename NodeT>
465 const Workset & workset_0 = (*d.worksets_)[0];
466 const std::string blockId = this->
wda(workset_0).block_id;
471 int maxElementBlockGIDCount = -1;
475 const int globalFieldNum =
globalIndexer_->getFieldNum(fieldName);
478 fieldIds_[fd] = subGlobalIndexer->getFieldNum(fieldName);
480 const std::vector<int>& offsets = subGlobalIndexer->getGIDFieldOffsets(blockId,
fieldIds_[fd]);
481 fieldOffsets_[fd] = PHX::View<int*>(
"GatherSolution_BlockedTpetra(Jacobian):fieldOffsets",offsets.size());
482 auto hostOffsets = Kokkos::create_mirror_view(
fieldOffsets_[fd]);
483 for (std::size_t i=0; i < offsets.size(); ++i)
484 hostOffsets(i) = offsets[i];
486 maxElementBlockGIDCount = std::max(subGlobalIndexer->getElementBlockGIDCount(blockId),maxElementBlockGIDCount);
492 worksetLIDs_ = PHX::View<LO**>(
"ScatterResidual_BlockedTpetra(Residual):worksetLIDs",
494 maxElementBlockGIDCount);
497 const auto& blockGlobalIndexers =
globalIndexer_->getFieldDOFManagers();
498 const int numBlocks =
static_cast<int>(
globalIndexer_->getFieldDOFManagers().size());
499 blockOffsets_ = PHX::View<LO*>(
"GatherSolution_BlockedTpetra(Jacobian):blockOffsets_",
501 const auto hostBlockOffsets = Kokkos::create_mirror_view(
blockOffsets_);
502 for (
int blk=0;blk<numBlocks;++blk) {
504 hostBlockOffsets(blk) = blockOffset;
506 hostBlockOffsets(numBlocks) = hostBlockOffsets(numBlocks-1) + blockGlobalIndexers[blockGlobalIndexers.size()-1]->getElementBlockGIDCount(blockId);
512template <
typename TRAITS,
typename S,
typename LO,
typename GO,
typename NodeT>
517 using Teuchos::rcp_dynamic_cast;
528 RCP<BVROGED> blockedGed = rcp_dynamic_cast<BVROGED>(d.gedc->getDataObject(
globalDataKey_+post),
true);
529 const int numBlocks =
static_cast<int>(
globalIndexer_->getFieldDOFManagers().size());
530 for(
int blk=0;blk<numBlocks;++blk)
531 solutionBlocks_.push_back(rcp_dynamic_cast<TVROGED>(blockedGed->getGEDBlock(blk),
true)->getGhostedVector_Tpetra());
542 TEUCHOS_TEST_FOR_EXCEPTION(blockedSolution==Teuchos::null,std::logic_error,
543 "GatherSolution_BlockedTpetra: the container under \"" <<
globalDataKey_ <<
"\" holds no "
546 auto prodSolution = rcp_dynamic_cast<const Thyra::ProductVectorBase<double> >(blockedSolution,
true);
547 for(
int blk=0;blk<prodSolution->productSpace()->numBlocks();++blk)
548 solutionBlocks_.push_back(rcp_dynamic_cast<
const Thyra::TpetraVector<S,LO,GO,NodeT> >(prodSolution->getVectorBlock(blk),
true)->getConstTpetraVector());
552template <
typename TRAITS,
typename S,
typename LO,
typename GO,
typename NodeT>
557 using Teuchos::rcp_dynamic_cast;
561 const auto& localCellIds = this->
wda(workset).cell_local_ids_k;
565 seedValue = workset.alpha;
567 seedValue = workset.beta;
576 int currentWorksetLIDSubBlock = -1;
577 for (std::size_t fieldIndex = 0; fieldIndex <
gatherFields_.size(); fieldIndex++) {
581 const std::string blockId = this->
wda(workset).block_id;
583 blockIndexer->getElementLIDs(localCellIds,
worksetLIDs_,num_dofs);
588 const auto kokkosSolution =
solutionBlocks_[blockRowIndex]->getLocalViewDevice(Tpetra::Access::ReadOnly);
591 const PHX::View<const int*> fieldOffsets =
fieldOffsets_[fieldIndex];
593 const PHX::View<ScalarT**> fieldValues =
gatherFields_[fieldIndex].get_static_view();
595 auto blockOffsets_h = Kokkos::create_mirror_view(blockOffsets);
596 Kokkos::deep_copy(blockOffsets_h, blockOffsets);
597 const int blockStart = blockOffsets_h(blockRowIndex);
599 Kokkos::parallel_for(Kokkos::RangePolicy<PHX::ExecutionSpace>(0,workset.num_cells), KOKKOS_LAMBDA (
const int& cell) {
600 for (
int basis=0; basis < static_cast<int>(fieldOffsets.size()); ++basis) {
601 const int rowLID = worksetLIDs(cell,fieldOffsets(basis));
602 fieldValues(cell,basis).zero();
603 fieldValues(cell,basis).val() = kokkosSolution(rowLID,0);
604 fieldValues(cell,basis).fastAccessDx(blockStart+fieldOffsets(basis)) = seedValue;
This class encapsulates the needs of a gather operation to do a halo exchange for blocked vectors.
WorksetDetailsAccessor wda
bool disableSensitivities_
std::vector< PHX::MDField< ScalarT, Cell, NODE > > gatherFields_
std::vector< int > fieldIds_
std::vector< std::string > indexerNames_
std::vector< int > productVectorBlockIndex_
PHX::View< LO ** > worksetLIDs_
Local indices for unknowns.
Teuchos::RCP< const BlockedDOFManager > globalIndexer_
bool useTimeDerivativeSolutionVector_
TRAITS::RealType RealType
Teuchos::RCP< const BlockedTpetraLinearObjContainer< S, LO, GO, NodeT > > blockedContainer_
std::vector< Teuchos::RCP< const VectorType > > solutionBlocks_
PHX::View< LO * > blockOffsets_
The offset values of the blocked DOFs per element. Size of number of blocks in the product vector + 1...
std::string globalDataKey_
std::vector< PHX::View< int * > > fieldOffsets_
Offset into the cell lids for each field. Size of number of fields to scatter.
bool useTimeDerivativeSolutionVector_
std::vector< PHX::View< int * > > fieldOffsets_
Offset into the cell lids for each field.
std::vector< PHX::MDField< ScalarT, Cell, NODE > > gatherFields_
Teuchos::RCP< const BlockedTpetraLinearObjContainer< S, LO, GO, NodeT > > blockedContainer_
std::string globalDataKey_
std::vector< int > productVectorBlockIndex_
Teuchos::RCP< const BlockedDOFManager > globalIndexer_
Maps the local (field,element,basis) triplet to a global ID for.
std::vector< std::string > indexerNames_
std::vector< Teuchos::RCP< const panzer::GlobalIndexer > > fieldGlobalIndexers_
Vector of global indexers, one for each field to gather, respectively.
std::vector< int > fieldIds_
Field IDs in the local product vector block (not global field id).
PHX::View< LO ** > worksetLIDs_
Local indices for unknowns.
std::vector< PHX::View< int * > > fieldOffsets_
Offset into the cell lids for each field. Size of number of fields to scatter.
Teuchos::RCP< const BlockedTpetraLinearObjContainer< S, LO, GO, NodeT > > blockedContainer_
PHX::ViewOfViews< 2, PHX::View< const RealT ** > > tangentFieldsVoV_
std::vector< int > productVectorBlockIndex_
Teuchos::RCP< const BlockedDOFManager > globalIndexer_
std::vector< std::string > indexerNames_
std::vector< PHX::MDField< ScalarT, Cell, NODE > > gatherFields_
bool useTimeDerivativeSolutionVector_
std::string globalDataKey_
PHX::View< LO ** > worksetLIDs_
Local indices for unknowns.
std::vector< std::vector< PHX::MDField< const RealT, Cell, NODE > > > tangentFields_
std::vector< int > fieldIds_
Gathers solution values from the Newton solution vector into the nodal fields of the field manager.
void postRegistrationSetup(typename TRAITS::SetupData d, PHX::FieldManager< TRAITS > &vm)
void evaluateFields(typename TRAITS::EvalData d)
GatherSolution_BlockedTpetra(const Teuchos::RCP< const BlockedDOFManager > &indexer)