30 const Teuchos::ParameterList& p,
31 bool useDiscreteAdjoint)
32 : rowIndexers_(rIndexers)
33 , colIndexers_(cIndexers)
34 , globalDataKey_(
"Residual Scatter Container")
35 , useDiscreteAdjoint_(useDiscreteAdjoint)
37 std::string scatterName = p.get<std::string>(
"Scatter Name");
39 Teuchos::rcp(
new PHX::Tag<ScalarT>(scatterName,Teuchos::rcp(
new PHX::MDALayout<Dummy>(0))));
42 const std::vector<std::string>& names =
43 *(p.get< Teuchos::RCP< std::vector<std::string> > >(
"Dependent Names"));
46 fieldMap_ = p.get< Teuchos::RCP< std::map<std::string,std::string> > >(
"Dependent Map");
48 Teuchos::RCP<PHX::DataLayout> dl =
49 p.get< Teuchos::RCP<const panzer::PureBasis> >(
"Basis")->functional;
52 scatterFields_.resize(names.size());
53 for (std::size_t eq = 0; eq < names.size(); ++eq) {
54 scatterFields_[eq] = PHX::MDField<const ScalarT,Cell,NODE>(names[eq],dl);
57 this->addDependentField(scatterFields_[eq]);
61 this->addEvaluatedField(*scatterHolder_);
63 if (p.isType<std::string>(
"Global Data Key"))
64 globalDataKey_ = p.get<std::string>(
"Global Data Key");
65 if (p.isType<
bool>(
"Use Discrete Adjoint"))
66 useDiscreteAdjoint = p.get<
bool>(
"Use Discrete Adjoint");
69 if(useDiscreteAdjoint)
70 { TEUCHOS_ASSERT(colIndexers_.size()==0); }
72 if(colIndexers_.size()==0)
73 colIndexers_ = rowIndexers_;
75 this->setName(scatterName+
" Scatter Residual BlockedEpetra (Hessian)");
103 using Teuchos::rcp_dynamic_cast;
109 RCP<const BLOC> blockedContainer = rcp_dynamic_cast<const BLOC>(d.gedc->getDataObject(globalDataKey_));
110 RCP<const ELOC> epetraContainer = rcp_dynamic_cast<const ELOC>(d.gedc->getDataObject(globalDataKey_));
113 if(blockedContainer!=Teuchos::null) {
114 Jac_ = rcp_dynamic_cast<Thyra::BlockedLinearOpBase<double> >(blockedContainer->get_A());
116 else if(epetraContainer!=Teuchos::null) {
118 RCP<Thyra::LinearOpBase<double> > J = blockedContainer->get_A_th();
119 Jac_ = rcp_dynamic_cast<Thyra::BlockedLinearOpBase<double> >(Thyra::nonconstBlock1x1(J));
122 TEUCHOS_ASSERT(Jac_!=Teuchos::null);
131 using Teuchos::ArrayRCP;
132 using Teuchos::ptrFromRef;
133 using Teuchos::rcp_dynamic_cast;
136 using Thyra::SpmdVectorBase;
140 std::vector<double> jacRow;
143 std::string blockId = this->wda(workset).block_id;
144 const std::vector<std::size_t> & localCellIds = this->wda(workset).cell_local_ids;
146 int numFieldBlocks = Teuchos::as<int>(colIndexers_.size());
148 std::vector<int> blockOffsets;
151 std::unordered_map<std::pair<int,int>,Teuchos::RCP<Epetra_CrsMatrix>,
panzer::pair_hash> jacEpetraBlocks;
154 for(std::size_t fieldIndex = 0; fieldIndex < scatterFields_.size(); fieldIndex++) {
155 int rowIndexer = indexerIds_[fieldIndex];
156 int subFieldNum = subFieldIds_[fieldIndex];
158 auto subRowIndexer = rowIndexers_[rowIndexer];
159 const std::vector<int> & elmtOffset = subRowIndexer->getGIDFieldOffsets(blockId,subFieldNum);
162 for(std::size_t worksetCellIndex=0;worksetCellIndex<localCellIds.size();++worksetCellIndex) {
163 std::size_t cellLocalId = localCellIds[worksetCellIndex];
165 auto rLIDs = subRowIndexer->getElementLIDs(cellLocalId);
168 for(std::size_t rowBasisNum = 0; rowBasisNum < elmtOffset.size(); rowBasisNum++) {
169 const ScalarT scatterField = (scatterFields_[fieldIndex])(worksetCellIndex,rowBasisNum);
170 int rowOffset = elmtOffset[rowBasisNum];
171 int r_lid = rLIDs[rowOffset];
174 jacRow.resize(scatterField.size());
177 if(scatterField.size() == 0)
180 for(
int sensIndex=0;sensIndex<scatterField.size();++sensIndex)
181 jacRow[sensIndex] = scatterField.fastAccessDx(sensIndex).fastAccessDx(0);
184 for(
int colIndexer=0;colIndexer<numFieldBlocks;colIndexer++) {
185 int start = blockOffsets[colIndexer];
186 int end = blockOffsets[colIndexer+1];
191 auto subColIndexer = colIndexers_[colIndexer];
192 auto cLIDs = subColIndexer->getElementLIDs(cellLocalId);
194 TEUCHOS_ASSERT(end-start==Teuchos::as<int>(cLIDs.size()));
197 std::pair<int,int> blockIndex = std::make_pair(rowIndexer,colIndexer);
198 Teuchos::RCP<Epetra_CrsMatrix> subJac = jacEpetraBlocks[blockIndex];
201 if(subJac==Teuchos::null) {
202 Teuchos::RCP<Thyra::LinearOpBase<double> > tOp = Jac_->getNonconstBlock(blockIndex.first,blockIndex.second);
205 if(Teuchos::is_null(tOp))
208 Teuchos::RCP<Epetra_Operator> eOp = Thyra::get_Epetra_Operator(*tOp);
209 subJac = rcp_dynamic_cast<Epetra_CrsMatrix>(eOp,
true);
210 jacEpetraBlocks[blockIndex] = subJac;
215 int err = subJac->SumIntoMyValues(r_lid, end-start, &jacRow[start],&cLIDs[0]);
218 std::stringstream ss;
219 ss <<
"Failed inserting row: " <<
"LID = " << r_lid <<
": ";
220 for(
int i=0;i<end-start;i++)
221 ss << cLIDs[i] <<
" ";
223 ss <<
"Into block " << rowIndexer <<
", " << colIndexer << std::endl;
225 ss <<
"scatter field = ";
226 scatterFields_[fieldIndex].print(ss);
230 for(
int i=start;i<end;i++)
231 ss << jacRow[i] <<
" ";
234 std::cout << ss.str() << std::endl;
236 TEUCHOS_TEST_FOR_EXCEPTION(err!=0,std::runtime_error,ss.str());