43 #ifndef PANZER_GATHER_SOLUTION_BLOCKED_EPETRA_IMPL_HPP 
   44 #define PANZER_GATHER_SOLUTION_BLOCKED_EPETRA_IMPL_HPP 
   46 #include "Teuchos_Assert.hpp" 
   47 #include "Phalanx_DataLayout.hpp" 
   52 #include "Panzer_TpetraLinearObjFactory.hpp" 
   57 #include "Teuchos_FancyOStream.hpp" 
   59 #include "Thyra_SpmdVectorBase.hpp" 
   60 #include "Thyra_ProductVectorBase.hpp" 
   62 #include "Tpetra_Map.hpp" 
   64 template <
typename EvalT,
typename TRAITS,
typename S,
typename LO,
typename GO,
typename NodeT>
 
   70   const std::vector<std::string>& names =
 
   76   for (std::size_t fd = 0; fd < names.size(); ++fd) {
 
   77     PHX::MDField<ScalarT,Cell,NODE> 
field = PHX::MDField<ScalarT,Cell,NODE>(names[fd],basis->
functional);
 
   78     this->addEvaluatedField(field.fieldTag());
 
   81   this->setName(
"Gather Solution");
 
   88 template <
typename TRAITS,
typename S,
typename LO,
typename GO,
typename NodeT>
 
   93   : globalIndexer_(indexer)
 
   94   , has_tangent_fields_(false)
 
   96   typedef std::vector< std::vector<std::string> > vvstring;
 
  101   const std::vector<std::string> & names      = input.
getDofNames();
 
  110   gatherFields_.resize(names.size());
 
  111   for (std::size_t fd = 0; fd < names.size(); ++fd) {
 
  113       PHX::MDField<ScalarT,Cell,NODE>(names[fd],basis->
functional);
 
  114     this->addEvaluatedField(gatherFields_[fd]);
 
  118   if (tangent_field_names.size()>0) {
 
  119     TEUCHOS_ASSERT(gatherFields_.size() == tangent_field_names.size());
 
  121     has_tangent_fields_ = 
true;
 
  122     tangentFields_.resize(gatherFields_.size());
 
  123     for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) {
 
  124       tangentFields_[fd].resize(tangent_field_names[fd].size());
 
  125       for (std::size_t i=0; i<tangent_field_names[fd].size(); ++i) {
 
  126         tangentFields_[fd][i] =
 
  127           PHX::MDField<const ScalarT,Cell,NODE>(tangent_field_names[fd][i],basis->
functional);
 
  128         this->addDependentField(tangentFields_[fd][i]);
 
  134   std::string firstName = 
"<none>";
 
  136     firstName = names[0];
 
  138   std::string n = 
"GatherSolution (BlockedTpetra): "+firstName+
" (Residual)";
 
  143 template <
typename TRAITS,
typename S,
typename LO,
typename GO,
typename NodeT>
 
  150   const Workset & workset_0 = (*d.worksets_)[0];
 
  151   const std::string blockId = this->wda(workset_0).
block_id;
 
  153   fieldIds_.resize(gatherFields_.size());
 
  154   fieldOffsets_.resize(gatherFields_.size());
 
  155   fieldGlobalIndexers_.resize(gatherFields_.size());
 
  156   productVectorBlockIndex_.resize(gatherFields_.size());
 
  157   int maxElementBlockGIDCount = -1;
 
  158   for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) {
 
  160     const std::string& fieldName = indexerNames_[fd];
 
  161     const int globalFieldNum = globalIndexer_->getFieldNum(fieldName); 
 
  162     productVectorBlockIndex_[fd] = globalIndexer_->getFieldBlock(globalFieldNum);
 
  163     fieldGlobalIndexers_[fd] = globalIndexer_->getFieldDOFManagers()[productVectorBlockIndex_[fd]];
 
  164     fieldIds_[fd] = fieldGlobalIndexers_[fd]->getFieldNum(fieldName); 
 
  166     const std::vector<int>& 
offsets = fieldGlobalIndexers_[fd]->getGIDFieldOffsets(blockId,fieldIds_[fd]);
 
  167     fieldOffsets_[fd] = Kokkos::View<int*,PHX::Device>(
"GatherSolution_BlockedTpetra(Residual):fieldOffsets",offsets.size());
 
  168     auto hostFieldOffsets = Kokkos::create_mirror_view(fieldOffsets_[fd]);
 
  169     for(std::size_t i=0; i < offsets.size(); ++i)
 
  170       hostFieldOffsets(i) = offsets[i];
 
  171     Kokkos::deep_copy(fieldOffsets_[fd],hostFieldOffsets);
 
  172     typename PHX::Device().fence();
 
  174     maxElementBlockGIDCount = std::max(fieldGlobalIndexers_[fd]->getElementBlockGIDCount(blockId),maxElementBlockGIDCount);
 
  180   worksetLIDs_ = Kokkos::View<LO**,PHX::Device>(
"GatherSolution_BlockedTpetra(Residual):worksetLIDs",
 
  181                                                 gatherFields_[0].extent(0),
 
  182                                                 maxElementBlockGIDCount);
 
  184   indexerNames_.clear();  
 
  188 template <
typename TRAITS,
typename S,
typename LO,
typename GO,
typename NodeT>
 
  193    blockedContainer_ = Teuchos::rcp_dynamic_cast<
const ContainerType>(d.gedc->getDataObject(globalDataKey_),
true);
 
  197 template <
typename TRAITS,
typename S,
typename LO,
typename GO,
typename NodeT>
 
  202   using Teuchos::rcp_dynamic_cast;
 
  206   const auto& localCellIds = this->wda(workset).cell_local_ids_k;
 
  209   if (useTimeDerivativeSolutionVector_)
 
  210     thyraBlockSolution = rcp_dynamic_cast<ProductVectorBase<ScalarT>>(blockedContainer_->get_dxdt(),
true);
 
  212     thyraBlockSolution = rcp_dynamic_cast<ProductVectorBase<ScalarT>>(blockedContainer_->get_x(),
true);
 
  215   int currentWorksetLIDSubBlock = -1;
 
  216   for (std::size_t fieldIndex = 0; fieldIndex < gatherFields_.size(); fieldIndex++) {
 
  218     if (productVectorBlockIndex_[fieldIndex] != currentWorksetLIDSubBlock) {
 
  219       fieldGlobalIndexers_[fieldIndex]->getElementLIDs(localCellIds,worksetLIDs_); 
 
  220       currentWorksetLIDSubBlock = productVectorBlockIndex_[fieldIndex];
 
  223     const auto& tpetraSolution = *((rcp_dynamic_cast<Thyra::TpetraVector<ScalarT,LO,GO,NodeT>>(thyraBlockSolution->getNonconstVectorBlock(productVectorBlockIndex_[fieldIndex]),
true))->getTpetraVector());
 
  224     const auto& kokkosSolution = tpetraSolution.template getLocalView<PHX::mem_space>();
 
  227     const auto& fieldOffsets = fieldOffsets_[fieldIndex];
 
  228     const auto& worksetLIDs = worksetLIDs_;
 
  229     const auto& fieldValues = gatherFields_[fieldIndex];
 
  231     Kokkos::parallel_for(Kokkos::RangePolicy<PHX::Device>(0,workset.num_cells), KOKKOS_LAMBDA (
const int& cell) {       
 
  232       for(
int basis=0; basis < static_cast<int>(fieldOffsets.size()); ++basis) {
 
  233         const int lid = worksetLIDs(cell,fieldOffsets(basis));
 
  234         fieldValues(cell,basis) = kokkosSolution(lid,0);        
 
  245 template <
typename TRAITS,
typename S,
typename LO,
typename GO,
typename NodeT>
 
  250   : gidIndexer_(indexer)
 
  251   , has_tangent_fields_(false)
 
  253   typedef std::vector< std::vector<std::string> > vvstring;
 
  258   const std::vector<std::string> & names      = input.
getDofNames();
 
  267   gatherFields_.resize(names.size());
 
  268   for (std::size_t fd = 0; fd < names.size(); ++fd) {
 
  270       PHX::MDField<ScalarT,Cell,NODE>(names[fd],basis->
functional);
 
  271     this->addEvaluatedField(gatherFields_[fd]);
 
  275   if (tangent_field_names.size()>0) {
 
  276     TEUCHOS_ASSERT(gatherFields_.size() == tangent_field_names.size());
 
  278     has_tangent_fields_ = 
true;
 
  279     tangentFields_.resize(gatherFields_.size());
 
  280     for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) {
 
  281       tangentFields_[fd].resize(tangent_field_names[fd].size());
 
  282       for (std::size_t i=0; i<tangent_field_names[fd].size(); ++i) {
 
  283         tangentFields_[fd][i] =
 
  284           PHX::MDField<const ScalarT,Cell,NODE>(tangent_field_names[fd][i],basis->
functional);
 
  285         this->addDependentField(tangentFields_[fd][i]);
 
  291   std::string firstName = 
"<none>";
 
  293     firstName = names[0];
 
  295   std::string n = 
"GatherSolution (BlockedTpetra): "+firstName+
" (Tangent)";
 
  300 template <
typename TRAITS,
typename S,
typename LO,
typename GO,
typename NodeT>
 
  307   fieldIds_.resize(gatherFields_.size());
 
  309   for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) {
 
  311     const std::string& fieldName = indexerNames_[fd];
 
  312     fieldIds_[fd] = gidIndexer_->getFieldNum(fieldName);
 
  315   indexerNames_.clear();  
 
  319 template <
typename TRAITS,
typename S,
typename LO,
typename GO,
typename NodeT>
 
  324    blockedContainer_ = Teuchos::rcp_dynamic_cast<
const ContainerType>(d.gedc->getDataObject(globalDataKey_),
true);
 
  328 template <
typename TRAITS,
typename S,
typename LO,
typename GO,
typename NodeT>
 
  334    using Teuchos::ptrFromRef;
 
  335    using Teuchos::rcp_dynamic_cast;
 
  338    using Thyra::SpmdVectorBase;
 
  345    std::vector<std::pair<int,GO> > GIDs;
 
  346    std::vector<LO> LIDs;
 
  349    std::string blockId = this->wda(workset).block_id;
 
  350    const std::vector<std::size_t> & localCellIds = this->wda(workset).cell_local_ids;
 
  353    if (useTimeDerivativeSolutionVector_)
 
  354      x = rcp_dynamic_cast<ProductVectorBase<double> >(blockedContainer_->get_dxdt());
 
  356      x = rcp_dynamic_cast<ProductVectorBase<double> >(blockedContainer_->get_x());
 
  359    for(std::size_t worksetCellIndex=0;worksetCellIndex<localCellIds.size();++worksetCellIndex) {
 
  360       LO cellLocalId = localCellIds[worksetCellIndex];
 
  362       gidIndexer_->getElementGIDsPair(cellLocalId,GIDs,blockId);
 
  365       LIDs.resize(GIDs.size());
 
  366       for(std::size_t i=0;i<GIDs.size();i++) {
 
  370          LIDs[i] = x_map->getLocalElement(GIDs[i].second);
 
  375       for (std::size_t fieldIndex=0; fieldIndex<gatherFields_.size();fieldIndex++) {
 
  376          int fieldNum = fieldIds_[fieldIndex];
 
  377          int indexerId = gidIndexer_->getFieldBlock(fieldNum);
 
  381          block_x->getLocalData(ptrFromRef(local_x));
 
  383          const std::vector<int> & elmtOffset = gidIndexer_->getGIDFieldOffsets(blockId,fieldNum);
 
  386          for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
 
  387             int offset = elmtOffset[basis];
 
  388             int lid = LIDs[offset];
 
  390             if (!has_tangent_fields_)
 
  391               (gatherFields_[fieldIndex])(worksetCellIndex,basis) = local_x[lid];
 
  393               (gatherFields_[fieldIndex])(worksetCellIndex,basis).val() = local_x[lid];
 
  394               for (std::size_t i=0; i<tangentFields_[fieldIndex].size(); ++i)
 
  395                 (gatherFields_[fieldIndex])(worksetCellIndex,basis).fastAccessDx(i) =
 
  396                   tangentFields_[fieldIndex][i](worksetCellIndex,basis).val();
 
  407 template <
typename TRAITS,
typename S,
typename LO,
typename GO,
typename NodeT>
 
  412   : globalIndexer_(indexer)
 
  417   const std::vector<std::string> & names      = input.
getDofNames();
 
  426   gatherFields_.resize(names.size());
 
  427   for (std::size_t fd = 0; fd < names.size(); ++fd) {
 
  428     PHX::MDField<ScalarT,Cell,NODE> f(names[fd],basis->
functional);
 
  429     gatherFields_[fd] = f;
 
  430     this->addEvaluatedField(gatherFields_[fd]);
 
  434   std::string firstName = 
"<none>";
 
  436     firstName = names[0];
 
  439   if(disableSensitivities_) {
 
  440     std::string n = 
"GatherSolution (BlockedTpetra, No Sensitivities): "+firstName+
" (Jacobian)";
 
  444     std::string n = 
"GatherSolution (BlockedTpetra): "+firstName+
" ("+PHX::print<EvalT>()+
") ";
 
  450 template <
typename TRAITS,
typename S,
typename LO,
typename GO,
typename NodeT>
 
  457   const Workset & workset_0 = (*d.worksets_)[0];
 
  458   const std::string blockId = this->wda(workset_0).
block_id;
 
  460   fieldIds_.resize(gatherFields_.size());
 
  461   fieldOffsets_.resize(gatherFields_.size());
 
  462   productVectorBlockIndex_.resize(gatherFields_.size());
 
  463   int maxElementBlockGIDCount = -1;
 
  464   for (std::size_t fd = 0; fd < gatherFields_.size(); ++fd) {
 
  466     const std::string fieldName = indexerNames_[fd];
 
  467     const int globalFieldNum = globalIndexer_->getFieldNum(fieldName); 
 
  468     productVectorBlockIndex_[fd] = globalIndexer_->getFieldBlock(globalFieldNum);
 
  469     const auto& subGlobalIndexer = globalIndexer_->getFieldDOFManagers()[productVectorBlockIndex_[fd]];
 
  470     fieldIds_[fd] = subGlobalIndexer->getFieldNum(fieldName); 
 
  472     const std::vector<int>& 
offsets = subGlobalIndexer->getGIDFieldOffsets(blockId,fieldIds_[fd]);
 
  473     fieldOffsets_[fd] = Kokkos::View<int*,PHX::Device>(
"GatherSolution_BlockedTpetra(Jacobian):fieldOffsets",offsets.size());
 
  474     auto hostOffsets = Kokkos::create_mirror_view(fieldOffsets_[fd]);
 
  475     for (std::size_t i=0; i < offsets.size(); ++i)
 
  476       hostOffsets(i) = offsets[i];
 
  477     Kokkos::deep_copy(fieldOffsets_[fd], hostOffsets);
 
  478     maxElementBlockGIDCount = std::max(subGlobalIndexer->getElementBlockGIDCount(blockId),maxElementBlockGIDCount);
 
  479     typename PHX::Device().fence();
 
  485   worksetLIDs_ = Kokkos::View<LO**,PHX::Device>(
"ScatterResidual_BlockedTpetra(Residual):worksetLIDs",
 
  486                                                 gatherFields_[0].extent(0),
 
  487                                                 maxElementBlockGIDCount);
 
  490   const auto& blockGlobalIndexers = globalIndexer_->getFieldDOFManagers();
 
  491   const int numBlocks = 
static_cast<int>(globalIndexer_->getFieldDOFManagers().size());
 
  492   blockOffsets_ = Kokkos::View<LO*,PHX::Device>(
"GatherSolution_BlockedTpetra(Jacobian):blockOffsets_",
 
  494   const auto hostBlockOffsets = Kokkos::create_mirror_view(blockOffsets_);
 
  495   for (
int blk=0;blk<numBlocks;++blk) {
 
  496     int blockOffset = globalIndexer_->getBlockGIDOffset(blockId,blk);
 
  497     hostBlockOffsets(blk) = blockOffset;
 
  499   blockOffsets_(numBlocks) = blockOffsets_(numBlocks-1) + blockGlobalIndexers[blockGlobalIndexers.size()-1]->getElementBlockGIDCount(blockId);
 
  500   Kokkos::deep_copy(blockOffsets_,hostBlockOffsets);
 
  502   indexerNames_.clear();  
 
  503   typename PHX::Device().fence();
 
  506 template <
typename TRAITS,
typename S,
typename LO,
typename GO,
typename NodeT>
 
  511    blockedContainer_ = Teuchos::rcp_dynamic_cast<
const ContainerType>(d.gedc->getDataObject(globalDataKey_),
true);
 
  515 template <
typename TRAITS,
typename S,
typename LO,
typename GO,
typename NodeT>
 
  520   using Teuchos::rcp_dynamic_cast;
 
  524   const auto& localCellIds = this->wda(workset).cell_local_ids_k;
 
  528   if (useTimeDerivativeSolutionVector_) {
 
  529     blockedSolution = rcp_dynamic_cast<ProductVectorBase<double> >(blockedContainer_->get_dxdt());
 
  530     seedValue = workset.alpha;
 
  533     blockedSolution = rcp_dynamic_cast<ProductVectorBase<double> >(blockedContainer_->get_x());
 
  534     seedValue = workset.beta;
 
  540   if(disableSensitivities_)
 
  543   const int numFieldBlocks = globalIndexer_->getNumFieldBlocks();
 
  546   int currentWorksetLIDSubBlock = -1;
 
  547   for (std::size_t fieldIndex = 0; fieldIndex < gatherFields_.size(); fieldIndex++) {
 
  549     if (productVectorBlockIndex_[fieldIndex] != currentWorksetLIDSubBlock) {
 
  550       const auto& blockIndexer = globalIndexer_->getFieldDOFManagers()[productVectorBlockIndex_[fieldIndex]];
 
  551       blockIndexer->getElementLIDs(localCellIds,worksetLIDs_); 
 
  552       currentWorksetLIDSubBlock = productVectorBlockIndex_[fieldIndex];
 
  555     const int blockRowIndex = productVectorBlockIndex_[fieldIndex];
 
  556     const auto& subblockSolution = *((rcp_dynamic_cast<Thyra::TpetraVector<RealType,LO,GO,NodeT>>(blockedSolution->getNonconstVectorBlock(blockRowIndex),
true))->getTpetraVector());
 
  557     const auto kokkosSolution = subblockSolution.template getLocalView<PHX::mem_space>();
 
  560     const Kokkos::View<const int*,PHX::Device> fieldOffsets = fieldOffsets_[fieldIndex];
 
  561     const Kokkos::View<const LO**,PHX::Device> worksetLIDs = worksetLIDs_;
 
  562     const PHX::View<ScalarT**> fieldValues = gatherFields_[fieldIndex].get_static_view();        
 
  563     const Kokkos::View<const LO*,PHX::Device> blockOffsets = blockOffsets_;
 
  564     const int blockStart = blockOffsets(blockRowIndex);
 
  565     const int numDerivatives = blockOffsets(numFieldBlocks);
 
  567     Kokkos::parallel_for(Kokkos::RangePolicy<PHX::Device>(0,workset.num_cells), KOKKOS_LAMBDA (
const int& cell) {  
 
  568       for (
int basis=0; basis < static_cast<int>(fieldOffsets.size()); ++basis) {
 
  569         const int rowLID = worksetLIDs(cell,fieldOffsets(basis));
 
  570         fieldValues(cell,basis) = 
ScalarT(numDerivatives,kokkosSolution(rowLID,0));
 
  571         fieldValues(cell,basis).fastAccessDx(blockStart+fieldOffsets(basis)) = seedValue;
 
GatherSolution_BlockedTpetra(const Teuchos::RCP< const BlockedDOFManager > &indexer)
 
void postRegistrationSetup(typename TRAITS::SetupData d, PHX::FieldManager< TRAITS > &vm)
 
basic_FancyOStream & setShowProcRank(const bool showProcRank)
 
T & get(const std::string &name, T def_value)
 
Gathers solution values from the Newton solution vector into the nodal fields of the field manager...
 
panzer::Traits::Jacobian::ScalarT ScalarT
 
TRAITS::RealType RealType
 
void evaluateFields(typename TRAITS::EvalData d)
 
basic_FancyOStream & setOutputToRootOnly(const int rootRank)
 
PHX::MDField< ScalarT, panzer::Cell, panzer::BASIS > field
A field to which we'll contribute, or in which we'll store, the result of computing this integral...
 
#define TEUCHOS_ASSERT(assertion_test)
 
Teuchos::RCP< PHX::DataLayout > functional
<Cell,Basis> or <Cell,Basis> 
 
Kokkos::View< const int *, PHX::Device > offsets