30 const Teuchos::ParameterList& p,
36 std::string scatterName = p.get<std::string>(
"Scatter Name");
38 Teuchos::rcp(
new PHX::Tag<ScalarT>(scatterName,Teuchos::rcp(
new PHX::MDALayout<Dummy>(0))));
41 const std::vector<std::string>& names =
42 *(p.get< Teuchos::RCP< std::vector<std::string> > >(
"Dependent Names"));
45 fieldMap_ = p.get< Teuchos::RCP< std::map<std::string,std::string> > >(
"Dependent Map");
47 Teuchos::RCP<PHX::DataLayout> dl =
48 p.get< Teuchos::RCP<panzer::PureBasis> >(
"Basis")->functional;
55 for (std::size_t eq = 0; eq < names.size(); ++eq) {
56 scatterFields_[eq] = PHX::MDField<const ScalarT,Cell,NODE>(names[eq],dl);
65 for (std::size_t eq = 0; eq < names.size(); ++eq) {
66 applyBC_[eq] = PHX::MDField<const bool,Cell,NODE>(std::string(
"APPLY_BC_")+
fieldMap_->find(names[eq])->second,dl);
67 this->addDependentField(
applyBC_[eq]);
74 if (p.isType<std::string>(
"Global Data Key"))
80 this->setName(scatterName+
" Scatter Dirichlet Residual : BlockedEpetra (Hessian)");
135 using Teuchos::ArrayRCP;
136 using Teuchos::ptrFromRef;
137 using Teuchos::rcp_dynamic_cast;
139 using Thyra::SpmdVectorBase;
142 std::string blockId = this->
wda(workset).block_id;
143 const std::vector<std::size_t> & localCellIds = this->
wda(workset).cell_local_ids;
145 int numFieldBlocks = Teuchos::as<int>(
colIndexers_.size());
147 std::vector<int> blockOffsets;
150 std::unordered_map<std::pair<int,int>,Teuchos::RCP<Epetra_CrsMatrix>,
panzer::pair_hash> jacEpetraBlocks;
157 for(std::size_t fieldIndex = 0; fieldIndex <
scatterFields_.size(); fieldIndex++) {
162 Teuchos::ArrayRCP<double> local_dc;
163 rcp_dynamic_cast<SpmdVectorBase<double> >(
dirichletCounter_->getNonconstVectorBlock(rowIndexer))
164 ->getNonconstLocalData(ptrFromRef(local_dc));
168 const std::vector<int> & subElmtOffset = subIndicePair.first;
169 const std::vector<int> & subBasisIdMap = subIndicePair.second;
172 for(std::size_t worksetCellIndex=0;worksetCellIndex<localCellIds.size();++worksetCellIndex) {
173 std::size_t cellLocalId = localCellIds[worksetCellIndex];
175 auto rLIDs = subRowIndexer->getElementLIDs(cellLocalId);
178 for(std::size_t basis=0;basis<subElmtOffset.size();basis++) {
179 int offset = subElmtOffset[basis];
180 int lid = rLIDs[offset];
184 int basisId = subBasisIdMap[basis];
187 if (!
applyBC_[fieldIndex](worksetCellIndex,basisId))
191 for(
int colIndexer=0;colIndexer<numFieldBlocks;colIndexer++) {
192 int start = blockOffsets[colIndexer];
193 int end = blockOffsets[colIndexer+1];
199 std::pair<int,int> blockIndex = std::make_pair(rowIndexer,colIndexer);
200 Teuchos::RCP<Epetra_CrsMatrix> subJac = jacEpetraBlocks[blockIndex];
202 if(subJac==Teuchos::null) {
203 Teuchos::RCP<Thyra::LinearOpBase<double> > tOp =
Jac_->getNonconstBlock(blockIndex.first,blockIndex.second);
206 if(Teuchos::is_null(tOp))
209 Teuchos::RCP<Epetra_Operator> eOp = Thyra::get_Epetra_Operator(*tOp);
210 subJac = rcp_dynamic_cast<Epetra_CrsMatrix>(eOp,
true);
211 jacEpetraBlocks[blockIndex] = subJac;
215 int * rowIndices = 0;
216 double * rowValues = 0;
218 subJac->ExtractMyRowView(lid,numEntries,rowValues,rowIndices);
220 for(
int i=0;i<numEntries;i++)
229 std::vector<double> jacRow(scatterField.size(),0.0);
231 for(
int sensIndex=0;sensIndex<scatterField.size();++sensIndex)
232 jacRow[sensIndex] = scatterField.fastAccessDx(sensIndex).fastAccessDx(0);
234 for(
int colIndexer=0;colIndexer<numFieldBlocks;colIndexer++) {
235 int start = blockOffsets[colIndexer];
236 int end = blockOffsets[colIndexer+1];
242 auto cLIDs = subColIndexer->getElementLIDs(cellLocalId);
244 TEUCHOS_ASSERT(end-start==Teuchos::as<int>(cLIDs.size()));
247 std::pair<int,int> blockIndex = std::make_pair(rowIndexer,colIndexer);
248 Teuchos::RCP<Epetra_CrsMatrix> subJac = jacEpetraBlocks[blockIndex];
251 if(subJac==Teuchos::null) {
252 Teuchos::RCP<Thyra::LinearOpBase<double> > tOp =
Jac_->getNonconstBlock(blockIndex.first,blockIndex.second);
255 if(Teuchos::is_null(tOp))
258 Teuchos::RCP<Epetra_Operator> eOp = Thyra::get_Epetra_Operator(*tOp);
259 subJac = rcp_dynamic_cast<Epetra_CrsMatrix>(eOp,
true);
260 jacEpetraBlocks[blockIndex] = subJac;
264 int err = subJac->ReplaceMyValues(lid, end-start, &jacRow[start],&cLIDs[0]);
266 std::stringstream ss;
267 ss <<
"Failed inserting row: " <<
" (" << lid <<
"): ";
268 for(
int i=0;i<end-start;i++)
269 ss << cLIDs[i] <<
" ";
271 ss <<
"Into block " << rowIndexer <<
", " << colIndexer << std::endl;
273 ss <<
"scatter field = ";
277 TEUCHOS_TEST_FOR_EXCEPTION(err!=0,std::runtime_error,ss.str());