43 #ifndef PANZER_SCATTER_DIRICHLET_RESIDUAL_BLOCEDEPETRA_IMPL_HPP 
   44 #define PANZER_SCATTER_DIRICHLET_RESIDUAL_BLOCEDEPETRA_IMPL_HPP 
   47 #include "Teuchos_Assert.hpp" 
   49 #include "Phalanx_DataLayout.hpp" 
   51 #include "Epetra_Map.h" 
   52 #include "Epetra_Vector.h" 
   53 #include "Epetra_CrsMatrix.h" 
   62 #include "Phalanx_DataLayout_MDALayout.hpp" 
   64 #include "Thyra_SpmdVectorBase.hpp" 
   65 #include "Thyra_ProductVectorBase.hpp" 
   66 #include "Thyra_DefaultProductVector.hpp" 
   67 #include "Thyra_BlockedLinearOpBase.hpp" 
   68 #include "Thyra_get_Epetra_Operator.hpp" 
   70 #include "Teuchos_FancyOStream.hpp" 
   72 #include <unordered_map> 
   79 template<
typename TRAITS,
typename LO,
typename GO>
 
   85    : rowIndexers_(rIndexers)
 
   86    , colIndexers_(cIndexers)
 
   87    , globalDataKey_(
"Residual Scatter Container")
 
   89   std::string scatterName = p.
get<std::string>(
"Scatter Name");
 
   94   const std::vector<std::string>& names = 
 
  101   scatterIC_ = p.
isParameter(
"Scatter Initial Condition") ? p.
get<
bool>(
"Scatter Initial Condition") : 
false;
 
  107     side_subcell_dim_ = p.
get<
int>(
"Side Subcell Dimension");
 
  108     local_side_id_ = p.
get<
int>(
"Local Side ID");
 
  112   scatterFields_.resize(names.size());
 
  113   for (std::size_t eq = 0; eq < names.size(); ++eq) {
 
  114     scatterFields_[eq] = PHX::MDField<const ScalarT,Cell,NODE>(names[eq],dl);
 
  117     this->addDependentField(scatterFields_[eq]);
 
  120   checkApplyBC_ = p.
isParameter(
"Check Apply BC") ? p.
get<
bool>(
"Check Apply BC") : 
false;
 
  122     applyBC_.resize(names.size());
 
  123     for (std::size_t eq = 0; eq < names.size(); ++eq) {
 
  124       applyBC_[eq] = PHX::MDField<const bool,Cell,NODE>(std::string(
"APPLY_BC_")+fieldMap_->find(names[eq])->second,dl);
 
  125       this->addDependentField(applyBC_[eq]);
 
  130   this->addEvaluatedField(*scatterHolder_);
 
  132   if (p.
isType<std::string>(
"Global Data Key"))
 
  133      globalDataKey_ = p.
get<std::string>(
"Global Data Key");
 
  135   this->setName(scatterName+
" Scatter Residual");
 
  139 template<
typename TRAITS,
typename LO,
typename GO> 
 
  144   indexerIds_.resize(scatterFields_.size());
 
  145   subFieldIds_.resize(scatterFields_.size());
 
  148   for(std::size_t fd=0;fd<scatterFields_.size();++fd) {
 
  150     std::string fieldName = fieldMap_->find(scatterFields_[fd].fieldTag().name())->second;
 
  153     subFieldIds_[fd] = rowIndexers_[indexerIds_[fd]]->getFieldNum(fieldName);
 
  157   num_nodes = scatterFields_[0].extent(1);
 
  161 template<
typename TRAITS,
typename LO,
typename GO>
 
  168    using Teuchos::rcp_dynamic_cast;
 
  173          = Teuchos::rcp_dynamic_cast<BLOC>(d.gedc->getDataObject(
"Dirichlet Counter"),
true);
 
  179    Teuchos::RCP<const BLOC> blockedContainer = Teuchos::rcp_dynamic_cast<
const BLOC>(d.gedc->getDataObject(globalDataKey_));
 
  180    Teuchos::RCP<const ELOC> epetraContainer  = Teuchos::rcp_dynamic_cast<
const ELOC>(d.gedc->getDataObject(globalDataKey_));
 
  183    if(blockedContainer!=Teuchos::null)
 
  185             rcp_dynamic_cast<ProductVectorBase<double> >(blockedContainer->get_f(),
true) :
 
  186             rcp_dynamic_cast<ProductVectorBase<double> >(blockedContainer->get_x(),
true);
 
  187    else if(epetraContainer!=Teuchos::null) 
 
  189             Thyra::castOrCreateNonconstProductVectorBase<double>(epetraContainer->get_f_th()) :
 
  190             Thyra::castOrCreateNonconstProductVectorBase<double>(epetraContainer->get_x_th());
 
  196 template<
typename TRAITS,
typename LO,
typename GO>
 
  202    using Teuchos::ptrFromRef;
 
  203    using Teuchos::rcp_dynamic_cast;
 
  206    using Thyra::SpmdVectorBase;
 
  210    std::string blockId = this->wda(workset).block_id;
 
  211    const std::vector<std::size_t> & localCellIds = this->wda(workset).cell_local_ids;
 
  221    for(std::size_t fieldIndex = 0; fieldIndex < scatterFields_.size(); fieldIndex++) {
 
  222       int rowIndexer  = indexerIds_[fieldIndex];
 
  223       int subFieldNum = subFieldIds_[fieldIndex];
 
  225       rcp_dynamic_cast<SpmdVectorBase<double> >(dirichletCounter_->getNonconstVectorBlock(rowIndexer))
 
  226                                                                  ->getNonconstLocalData(ptrFromRef(local_dc));
 
  229       rcp_dynamic_cast<SpmdVectorBase<double> >(r_->getNonconstVectorBlock(rowIndexer))
 
  230                                                   ->getNonconstLocalData(ptrFromRef(local_r));
 
  232       auto subRowIndexer = rowIndexers_[rowIndexer];
 
  235       for(std::size_t worksetCellIndex=0;worksetCellIndex<localCellIds.size();++worksetCellIndex) {
 
  236          std::size_t cellLocalId = localCellIds[worksetCellIndex];
 
  238    auto LIDs = subRowIndexer->getElementLIDs(cellLocalId); 
 
  242            const std::pair<std::vector<int>,std::vector<int> > & indicePair 
 
  243              = subRowIndexer->getGIDFieldOffsets_closure(blockId,subFieldNum, side_subcell_dim_, local_side_id_);
 
  244            const std::vector<int> & elmtOffset = indicePair.first;
 
  245            const std::vector<int> & basisIdMap = indicePair.second;
 
  248            for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
 
  249              int offset = elmtOffset[basis];
 
  250              int lid = LIDs[offset];
 
  254              int basisId = basisIdMap[basis];
 
  257                if (!applyBC_[fieldIndex](worksetCellIndex,basisId))
 
  260              local_r[lid] = (scatterFields_[fieldIndex])(worksetCellIndex,basisId);
 
  267            const std::vector<int> & elmtOffset = subRowIndexer->getGIDFieldOffsets(blockId,subFieldNum);
 
  270            for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
 
  271              int offset = elmtOffset[basis];
 
  272              int lid = LIDs[offset];
 
  276              local_r[lid] = (scatterFields_[fieldIndex])(worksetCellIndex,basis);
 
  291 template<
typename TRAITS,
typename LO,
typename GO>
 
  297    : rowIndexers_(rIndexers)
 
  298    , colIndexers_(cIndexers)
 
  299    , globalDataKey_(
"Residual Scatter Container")
 
  301   std::string scatterName = p.
get<std::string>(
"Scatter Name");
 
  306   const std::vector<std::string>& names = 
 
  313   scatterIC_ = p.
isParameter(
"Scatter Initial Condition") ? p.
get<
bool>(
"Scatter Initial Condition") : 
false;
 
  319     side_subcell_dim_ = p.
get<
int>(
"Side Subcell Dimension");
 
  320     local_side_id_ = p.
get<
int>(
"Local Side ID");
 
  324   scatterFields_.resize(names.size());
 
  325   for (std::size_t eq = 0; eq < names.size(); ++eq) {
 
  326     scatterFields_[eq] = PHX::MDField<const ScalarT,Cell,NODE>(names[eq],dl);
 
  329     this->addDependentField(scatterFields_[eq]);
 
  332   checkApplyBC_ = p.
isParameter(
"Check Apply BC") ? p.
get<
bool>(
"Check Apply BC") : 
false;
 
  334     applyBC_.resize(names.size());
 
  335     for (std::size_t eq = 0; eq < names.size(); ++eq) {
 
  336       applyBC_[eq] = PHX::MDField<const bool,Cell,NODE>(std::string(
"APPLY_BC_")+fieldMap_->find(names[eq])->second,dl);
 
  337       this->addDependentField(applyBC_[eq]);
 
  342   this->addEvaluatedField(*scatterHolder_);
 
  344   if (p.
isType<std::string>(
"Global Data Key"))
 
  345      globalDataKey_ = p.
get<std::string>(
"Global Data Key");
 
  347   this->setName(scatterName+
" Scatter Tangent");
 
  351 template<
typename TRAITS,
typename LO,
typename GO> 
 
  356   indexerIds_.resize(scatterFields_.size());
 
  357   subFieldIds_.resize(scatterFields_.size());
 
  360   for(std::size_t fd=0;fd<scatterFields_.size();++fd) {
 
  362     std::string fieldName = fieldMap_->find(scatterFields_[fd].fieldTag().name())->second;
 
  365     subFieldIds_[fd] = rowIndexers_[indexerIds_[fd]]->getFieldNum(fieldName);
 
  369   num_nodes = scatterFields_[0].extent(1);
 
  373 template<
typename TRAITS,
typename LO,
typename GO>
 
  380    using Teuchos::rcp_dynamic_cast;
 
  385          = Teuchos::rcp_dynamic_cast<BLOC>(d.gedc->getDataObject(
"Dirichlet Counter"),
true);
 
  391    Teuchos::RCP<const BLOC> blockedContainer = Teuchos::rcp_dynamic_cast<
const BLOC>(d.gedc->getDataObject(globalDataKey_));
 
  392    Teuchos::RCP<const ELOC> epetraContainer  = Teuchos::rcp_dynamic_cast<
const ELOC>(d.gedc->getDataObject(globalDataKey_));
 
  395    if(blockedContainer!=Teuchos::null)
 
  397             rcp_dynamic_cast<ProductVectorBase<double> >(blockedContainer->get_f(),
true) :
 
  398             rcp_dynamic_cast<ProductVectorBase<double> >(blockedContainer->get_x(),
true);
 
  399    else if(epetraContainer!=Teuchos::null) 
 
  401             Thyra::castOrCreateNonconstProductVectorBase<double>(epetraContainer->get_f_th()) :
 
  402             Thyra::castOrCreateNonconstProductVectorBase<double>(epetraContainer->get_x_th());
 
  408 template<
typename TRAITS,
typename LO,
typename GO>
 
  416    using Teuchos::ptrFromRef;
 
  417    using Teuchos::rcp_dynamic_cast;
 
  420    using Thyra::SpmdVectorBase;
 
  424    std::string blockId = this->wda(workset).block_id;
 
  425    const std::vector<std::size_t> & localCellIds = this->wda(workset).cell_local_ids;
 
  435    for(std::size_t fieldIndex = 0; fieldIndex < scatterFields_.size(); fieldIndex++) {
 
  436       int rowIndexer  = indexerIds_[fieldIndex];
 
  437       int subFieldNum = subFieldIds_[fieldIndex];
 
  439       rcp_dynamic_cast<SpmdVectorBase<double> >(dirichletCounter_->getNonconstVectorBlock(rowIndexer))
 
  440                                                                  ->getNonconstLocalData(ptrFromRef(local_dc));
 
  443       rcp_dynamic_cast<SpmdVectorBase<double> >(r_->getNonconstVectorBlock(rowIndexer))
 
  444                                                   ->getNonconstLocalData(ptrFromRef(local_r));
 
  446       auto subRowIndexer = rowIndexers_[rowIndexer];
 
  449       for(std::size_t worksetCellIndex=0;worksetCellIndex<localCellIds.size();++worksetCellIndex) {
 
  450          std::size_t cellLocalId = localCellIds[worksetCellIndex];
 
  452    auto LIDs = subRowIndexer->getElementLIDs(cellLocalId); 
 
  456            const std::pair<std::vector<int>,std::vector<int> > & indicePair 
 
  457              = subRowIndexer->getGIDFieldOffsets_closure(blockId,subFieldNum, side_subcell_dim_, local_side_id_);
 
  458            const std::vector<int> & elmtOffset = indicePair.first;
 
  459            const std::vector<int> & basisIdMap = indicePair.second;
 
  462            for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
 
  463              int offset = elmtOffset[basis];
 
  464              int lid = LIDs[offset];
 
  468              int basisId = basisIdMap[basis];
 
  471                if (!applyBC_[fieldIndex](worksetCellIndex,basisId))
 
  474              local_r[lid] = (scatterFields_[fieldIndex])(worksetCellIndex,basisId).val();
 
  481            const std::vector<int> & elmtOffset = subRowIndexer->getGIDFieldOffsets(blockId,subFieldNum);
 
  484            for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
 
  485              int offset = elmtOffset[basis];
 
  486              int lid = LIDs[offset];
 
  490              local_r[lid] = (scatterFields_[fieldIndex])(worksetCellIndex,basis).val();
 
  504 template<
typename TRAITS,
typename LO,
typename GO>
 
  510    : rowIndexers_(rIndexers)
 
  511    , colIndexers_(cIndexers)
 
  512    , globalDataKey_(
"Residual Scatter Container")
 
  514   std::string scatterName = p.
get<std::string>(
"Scatter Name");
 
  519   const std::vector<std::string>& names = 
 
  528   side_subcell_dim_ = p.
get<
int>(
"Side Subcell Dimension");
 
  529   local_side_id_ = p.
get<
int>(
"Local Side ID");
 
  532   scatterFields_.resize(names.size());
 
  533   for (std::size_t eq = 0; eq < names.size(); ++eq) {
 
  534     scatterFields_[eq] = PHX::MDField<const ScalarT,Cell,NODE>(names[eq],dl);
 
  537     this->addDependentField(scatterFields_[eq]);
 
  540   checkApplyBC_ = p.
get<
bool>(
"Check Apply BC");
 
  542     applyBC_.resize(names.size());
 
  543     for (std::size_t eq = 0; eq < names.size(); ++eq) {
 
  544       applyBC_[eq] = PHX::MDField<const bool,Cell,NODE>(std::string(
"APPLY_BC_")+fieldMap_->find(names[eq])->second,dl);
 
  545       this->addDependentField(applyBC_[eq]);
 
  550   this->addEvaluatedField(*scatterHolder_);
 
  552   if (p.
isType<std::string>(
"Global Data Key"))
 
  553      globalDataKey_ = p.
get<std::string>(
"Global Data Key");
 
  555   if(colIndexers_.size()==0)
 
  556     colIndexers_ = rowIndexers_;
 
  558   this->setName(scatterName+
" Scatter Residual (Jacobian)");
 
  562 template<
typename TRAITS,
typename LO,
typename GO> 
 
  567   indexerIds_.resize(scatterFields_.size());
 
  568   subFieldIds_.resize(scatterFields_.size());
 
  571   for(std::size_t fd=0;fd<scatterFields_.size();++fd) {
 
  573     std::string fieldName = fieldMap_->find(scatterFields_[fd].fieldTag().name())->second;
 
  576     subFieldIds_[fd] = rowIndexers_[indexerIds_[fd]]->getFieldNum(fieldName);
 
  580   num_nodes = scatterFields_[0].extent(1);
 
  581   num_eq = scatterFields_.size();
 
  585 template<
typename TRAITS,
typename LO,
typename GO>
 
  591    using Teuchos::rcp_dynamic_cast;
 
  595          = rcp_dynamic_cast<
const BLOC>(d.gedc->getDataObject(
"Dirichlet Counter"),
true);
 
  601    blockContainer = rcp_dynamic_cast<
const BLOC>(d.gedc->getDataObject(globalDataKey_),
true);
 
  609 template<
typename TRAITS,
typename LO,
typename GO>
 
  615    using Teuchos::ptrFromRef;
 
  616    using Teuchos::rcp_dynamic_cast;
 
  618    using Thyra::SpmdVectorBase;
 
  621    std::string blockId = this->wda(workset).block_id;
 
  622    const std::vector<std::size_t> & localCellIds = this->wda(workset).cell_local_ids;
 
  624    int numFieldBlocks = Teuchos::as<int>(colIndexers_.size());
 
  626    std::vector<int> blockOffsets;
 
  636    for(std::size_t fieldIndex = 0; fieldIndex < scatterFields_.size(); fieldIndex++) {
 
  637       int rowIndexer  = indexerIds_[fieldIndex];
 
  638       int subFieldNum = subFieldIds_[fieldIndex];
 
  642       rcp_dynamic_cast<SpmdVectorBase<double> >(dirichletCounter_->getNonconstVectorBlock(rowIndexer))
 
  643                                                                  ->getNonconstLocalData(ptrFromRef(local_dc));
 
  647       if(r_!=Teuchos::null)
 
  648         rcp_dynamic_cast<SpmdVectorBase<double> >(r_->getNonconstVectorBlock(rowIndexer))
 
  649                                                     ->getNonconstLocalData(ptrFromRef(local_r));
 
  651       auto subRowIndexer = rowIndexers_[rowIndexer];
 
  652       auto subIndicePair = subRowIndexer->getGIDFieldOffsets_closure(blockId,subFieldNum, side_subcell_dim_, local_side_id_);
 
  653       const std::vector<int> & subElmtOffset = subIndicePair.first;
 
  654       const std::vector<int> & subBasisIdMap = subIndicePair.second;
 
  657       for(std::size_t worksetCellIndex=0;worksetCellIndex<localCellIds.size();++worksetCellIndex) {
 
  658          std::size_t cellLocalId = localCellIds[worksetCellIndex];
 
  660    auto rLIDs = subRowIndexer->getElementLIDs(cellLocalId); 
 
  663          for(std::size_t basis=0;basis<subElmtOffset.size();basis++) {
 
  664             int offset = subElmtOffset[basis];
 
  665             int lid = rLIDs[offset];
 
  669             int basisId = subBasisIdMap[basis];
 
  672               if (!applyBC_[fieldIndex](worksetCellIndex,basisId))
 
  676             for(
int colIndexer=0;colIndexer<numFieldBlocks;colIndexer++) {
 
  677                int start = blockOffsets[colIndexer];
 
  678                int end = blockOffsets[colIndexer+1];
 
  684                std::pair<int,int> blockIndex = std::make_pair(rowIndexer,colIndexer);
 
  685                Teuchos::RCP<Epetra_CrsMatrix> subJac = jacEpetraBlocks[blockIndex];
 
  687                if(subJac==Teuchos::null) {
 
  696                   jacEpetraBlocks[blockIndex] = subJac;
 
  700                int * rowIndices = 0;
 
  701                double * rowValues = 0;
 
  705                for(
int i=0;i<numEntries;i++)
 
  709             const ScalarT scatterField = (scatterFields_[fieldIndex])(worksetCellIndex,basisId);
 
  711             if(r_!=Teuchos::null)
 
  712               local_r[lid] = scatterField.val();
 
  716             std::vector<double> jacRow(scatterField.size(),0.0);
 
  718             for(
int sensIndex=0;sensIndex<scatterField.size();++sensIndex)
 
  719                jacRow[sensIndex] = scatterField.fastAccessDx(sensIndex);
 
  721             for(
int colIndexer=0;colIndexer<numFieldBlocks;colIndexer++) {
 
  722                int start = blockOffsets[colIndexer];
 
  723                int end = blockOffsets[colIndexer+1];
 
  728                auto subColIndexer = colIndexers_[colIndexer];
 
  729          auto cLIDs = subColIndexer->getElementLIDs(cellLocalId); 
 
  734                std::pair<int,int> blockIndex = std::make_pair(rowIndexer,colIndexer);
 
  735                Teuchos::RCP<Epetra_CrsMatrix> subJac = jacEpetraBlocks[blockIndex];
 
  738                if(subJac==Teuchos::null) {
 
  747                   jacEpetraBlocks[blockIndex] = subJac;
 
  751                int err = subJac->
ReplaceMyValues(lid, end-start, &jacRow[start],&cLIDs[0]);
 
  753                  std::stringstream ss;
 
  754                  ss << 
"Failed inserting row: " << 
" (" << lid << 
"): ";
 
  755                  for(
int i=0;i<end-start;i++)
 
  756                    ss << cLIDs[i] << 
" ";
 
  758                  ss << 
"Into block " << rowIndexer << 
", " << colIndexer << std::endl;
 
  760                  ss << 
"scatter field = ";
 
  761                  scatterFields_[fieldIndex].print(ss);
 
T & get(const std::string &name, T def_value)
 
bool is_null(const std::shared_ptr< T > &p)
 
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
 
void postRegistrationSetup(typename TRAITS::SetupData d, PHX::FieldManager< TRAITS > &vm)
 
void computeBlockOffsets(const std::string &blockId, const std::vector< Teuchos::RCP< GlobalIndexer >> &ugis, std::vector< int > &blockOffsets)
 
int ExtractMyRowView(int MyRow, int &NumEntries, double *&Values, int *&Indices) const 
 
Pushes residual values into the residual vector for a Newton-based solve. 
 
bool isParameter(const std::string &name) const 
 
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
 
void evaluateFields(typename TRAITS::EvalData d)
 
int getFieldBlock(const std::string &fieldName, const std::vector< Teuchos::RCP< const GlobalIndexer >> &ugis)
 
ScatterDirichletResidual_BlockedEpetra(const Teuchos::ParameterList &p)
 
panzer::Traits::Jacobian::ScalarT ScalarT
 
bool isType(const std::string &name) const 
 
#define TEUCHOS_ASSERT(assertion_test)
 
int ReplaceMyValues(int MyRow, int NumEntries, const double *Values, const int *Indices)