50 const std::vector<Teuchos::RCP<const GlobalIndexer> > & cIndexers,
51 const Teuchos::ParameterList& p,
57 std::string scatterName = p.get<std::string>(
"Scatter Name");
59 Teuchos::rcp(
new PHX::Tag<ScalarT>(scatterName,Teuchos::rcp(
new PHX::MDALayout<Dummy>(0))));
62 const std::vector<std::string>& names =
63 *(p.get< Teuchos::RCP< std::vector<std::string> > >(
"Dependent Names"));
66 fieldMap_ = p.get< Teuchos::RCP< std::map<std::string,std::string> > >(
"Dependent Map");
69 scatterIC_ = p.isParameter(
"Scatter Initial Condition") ? p.get<
bool>(
"Scatter Initial Condition") :
false;
71 Teuchos::RCP<PHX::DataLayout> dl = (!
scatterIC_) ?
72 p.get< Teuchos::RCP<panzer::PureBasis> >(
"Basis")->functional :
73 p.get< Teuchos::RCP<const panzer::PureBasis> >(
"Basis")->functional;
81 for (std::size_t eq = 0; eq < names.size(); ++eq) {
82 scatterFields_[eq] = PHX::MDField<const ScalarT,Cell,NODE>(names[eq],dl);
88 checkApplyBC_ = p.isParameter(
"Check Apply BC") ? p.get<
bool>(
"Check Apply BC") :
false;
91 for (std::size_t eq = 0; eq < names.size(); ++eq) {
92 applyBC_[eq] = PHX::MDField<const bool,Cell,NODE>(std::string(
"APPLY_BC_")+
fieldMap_->find(names[eq])->second,dl);
93 this->addDependentField(
applyBC_[eq]);
100 if (p.isType<std::string>(
"Global Data Key"))
103 this->setName(scatterName+
" Scatter Residual");
169 using Teuchos::ArrayRCP;
170 using Teuchos::ptrFromRef;
171 using Teuchos::rcp_dynamic_cast;
174 using Thyra::SpmdVectorBase;
178 std::string blockId = this->
wda(workset).block_id;
179 const std::vector<std::size_t> & localCellIds = this->
wda(workset).cell_local_ids;
187 Teuchos::ArrayRCP<double> local_r;
188 Teuchos::ArrayRCP<double> local_dc;
189 for(std::size_t fieldIndex = 0; fieldIndex <
scatterFields_.size(); fieldIndex++) {
193 rcp_dynamic_cast<SpmdVectorBase<double> >(
dirichletCounter_->getNonconstVectorBlock(rowIndexer))
194 ->getNonconstLocalData(ptrFromRef(local_dc));
197 rcp_dynamic_cast<SpmdVectorBase<double> >(
r_->getNonconstVectorBlock(rowIndexer))
198 ->getNonconstLocalData(ptrFromRef(local_r));
201 auto LIDs = subRowIndexer->getLIDs();
202 auto LIDs_h = Kokkos::create_mirror_view(LIDs);
203 Kokkos::deep_copy(LIDs_h, LIDs);
206 auto field_h = Kokkos::create_mirror_view(field);
207 Kokkos::deep_copy(field_h, field);
209 BCFieldType::array_type::host_mirror_type applyBC_h;
211 auto applyBC =
applyBC_[fieldIndex].get_static_view();
212 applyBC_h = Kokkos::create_mirror_view(applyBC);
213 Kokkos::deep_copy(applyBC_h, applyBC);
217 for(std::size_t worksetCellIndex=0;worksetCellIndex<localCellIds.size();++worksetCellIndex) {
218 std::size_t cellLocalId = localCellIds[worksetCellIndex];
222 const std::pair<std::vector<int>,std::vector<int> > & indicePair
224 const std::vector<int> & elmtOffset = indicePair.first;
225 const std::vector<int> & basisIdMap = indicePair.second;
228 for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
229 int offset = elmtOffset[basis];
230 int lid = LIDs_h(cellLocalId, offset);
234 int basisId = basisIdMap[basis];
239 local_r[lid] = field_h(worksetCellIndex,basisId);
246 const std::vector<int> & elmtOffset = subRowIndexer->getGIDFieldOffsets(blockId,subFieldNum);
249 for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
250 int offset = elmtOffset[basis];
251 int lid = LIDs_h(cellLocalId, offset);
255 local_r[lid] = field_h(worksetCellIndex,basis);
273 const std::vector<Teuchos::RCP<const GlobalIndexer> > & cIndexers,
274 const Teuchos::ParameterList& p,
280 std::string scatterName = p.get<std::string>(
"Scatter Name");
282 Teuchos::rcp(
new PHX::Tag<ScalarT>(scatterName,Teuchos::rcp(
new PHX::MDALayout<Dummy>(0))));
285 const std::vector<std::string>& names =
286 *(p.get< Teuchos::RCP< std::vector<std::string> > >(
"Dependent Names"));
289 fieldMap_ = p.get< Teuchos::RCP< std::map<std::string,std::string> > >(
"Dependent Map");
292 scatterIC_ = p.isParameter(
"Scatter Initial Condition") ? p.get<
bool>(
"Scatter Initial Condition") :
false;
294 Teuchos::RCP<PHX::DataLayout> dl = (!
scatterIC_) ?
295 p.get< Teuchos::RCP<panzer::PureBasis> >(
"Basis")->functional :
296 p.get< Teuchos::RCP<const panzer::PureBasis> >(
"Basis")->functional;
304 for (std::size_t eq = 0; eq < names.size(); ++eq) {
305 scatterFields_[eq] = PHX::MDField<const ScalarT,Cell,NODE>(names[eq],dl);
311 checkApplyBC_ = p.isParameter(
"Check Apply BC") ? p.get<
bool>(
"Check Apply BC") :
false;
314 for (std::size_t eq = 0; eq < names.size(); ++eq) {
315 applyBC_[eq] = PHX::MDField<const bool,Cell,NODE>(std::string(
"APPLY_BC_")+
fieldMap_->find(names[eq])->second,dl);
316 this->addDependentField(
applyBC_[eq]);
323 if (p.isType<std::string>(
"Global Data Key"))
326 this->setName(scatterName+
" Scatter Tangent");
391 TEUCHOS_ASSERT(
false);
394 using Teuchos::ArrayRCP;
395 using Teuchos::ptrFromRef;
396 using Teuchos::rcp_dynamic_cast;
399 using Thyra::SpmdVectorBase;
403 std::string blockId = this->
wda(workset).block_id;
404 const std::vector<std::size_t> & localCellIds = this->
wda(workset).cell_local_ids;
412 Teuchos::ArrayRCP<double> local_r;
413 Teuchos::ArrayRCP<double> local_dc;
414 for(std::size_t fieldIndex = 0; fieldIndex <
scatterFields_.size(); fieldIndex++) {
418 rcp_dynamic_cast<SpmdVectorBase<double> >(
dirichletCounter_->getNonconstVectorBlock(rowIndexer))
419 ->getNonconstLocalData(ptrFromRef(local_dc));
422 rcp_dynamic_cast<SpmdVectorBase<double> >(
r_->getNonconstVectorBlock(rowIndexer))
423 ->getNonconstLocalData(ptrFromRef(local_r));
427 auto LIDs = subRowIndexer->getLIDs();
428 auto LIDs_h = Kokkos::create_mirror_view(LIDs);
429 Kokkos::deep_copy(LIDs_h, LIDs);
432 auto field_h = Kokkos::create_mirror_view(field);
433 Kokkos::deep_copy(field_h, field);
435 BCFieldType::array_type::host_mirror_type applyBC_h;
437 auto applyBC =
applyBC_[fieldIndex].get_static_view();
438 applyBC_h = Kokkos::create_mirror_view(applyBC);
439 Kokkos::deep_copy(applyBC_h, applyBC);
443 for(std::size_t worksetCellIndex=0;worksetCellIndex<localCellIds.size();++worksetCellIndex) {
444 std::size_t cellLocalId = localCellIds[worksetCellIndex];
448 const std::pair<std::vector<int>,std::vector<int> > & indicePair
450 const std::vector<int> & elmtOffset = indicePair.first;
451 const std::vector<int> & basisIdMap = indicePair.second;
454 for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
455 int offset = elmtOffset[basis];
456 int lid = LIDs_h(cellLocalId, offset);
460 int basisId = basisIdMap[basis];
465 local_r[lid] = field_h(worksetCellIndex,basisId).val();
472 const std::vector<int> & elmtOffset = subRowIndexer->getGIDFieldOffsets(blockId,subFieldNum);
475 for(std::size_t basis=0;basis<elmtOffset.size();basis++) {
476 int offset = elmtOffset[basis];
477 int lid = LIDs_h(cellLocalId, offset);
481 local_r[lid] = field_h(worksetCellIndex,basis).val();
498 const std::vector<Teuchos::RCP<const GlobalIndexer> > & cIndexers,
499 const Teuchos::ParameterList& p,
505 std::string scatterName = p.get<std::string>(
"Scatter Name");
507 Teuchos::rcp(
new PHX::Tag<ScalarT>(scatterName,Teuchos::rcp(
new PHX::MDALayout<Dummy>(0))));
510 const std::vector<std::string>& names =
511 *(p.get< Teuchos::RCP< std::vector<std::string> > >(
"Dependent Names"));
514 fieldMap_ = p.get< Teuchos::RCP< std::map<std::string,std::string> > >(
"Dependent Map");
516 Teuchos::RCP<PHX::DataLayout> dl =
517 p.get< Teuchos::RCP<panzer::PureBasis> >(
"Basis")->functional;
524 for (std::size_t eq = 0; eq < names.size(); ++eq) {
525 scatterFields_[eq] = PHX::MDField<const ScalarT,Cell,NODE>(names[eq],dl);
534 for (std::size_t eq = 0; eq < names.size(); ++eq) {
535 applyBC_[eq] = PHX::MDField<const bool,Cell,NODE>(std::string(
"APPLY_BC_")+
fieldMap_->find(names[eq])->second,dl);
536 this->addDependentField(
applyBC_[eq]);
543 if (p.isType<std::string>(
"Global Data Key"))
549 this->setName(scatterName+
" Scatter Residual (Jacobian)");
605 using Teuchos::ArrayRCP;
606 using Teuchos::ptrFromRef;
607 using Teuchos::rcp_dynamic_cast;
609 using Thyra::SpmdVectorBase;
612 std::string blockId = this->
wda(workset).block_id;
613 const std::vector<std::size_t> & localCellIds = this->
wda(workset).cell_local_ids;
615 int numFieldBlocks = Teuchos::as<int>(
colIndexers_.size());
617 std::vector<int> blockOffsets;
620 std::unordered_map<std::pair<int,int>,Teuchos::RCP<Epetra_CrsMatrix>,
panzer::pair_hash> jacEpetraBlocks;
627 for(std::size_t fieldIndex = 0; fieldIndex <
scatterFields_.size(); fieldIndex++) {
632 Teuchos::ArrayRCP<double> local_dc;
633 rcp_dynamic_cast<SpmdVectorBase<double> >(
dirichletCounter_->getNonconstVectorBlock(rowIndexer))
634 ->getNonconstLocalData(ptrFromRef(local_dc));
637 Teuchos::ArrayRCP<double> local_r;
638 if(
r_!=Teuchos::null)
639 rcp_dynamic_cast<SpmdVectorBase<double> >(
r_->getNonconstVectorBlock(rowIndexer))
640 ->getNonconstLocalData(ptrFromRef(local_r));
644 const std::vector<int> & subElmtOffset = subIndicePair.first;
645 const std::vector<int> & subBasisIdMap = subIndicePair.second;
647 auto rLIDs = subRowIndexer->getLIDs();
648 auto rLIDs_h = Kokkos::create_mirror_view(rLIDs);
649 Kokkos::deep_copy(rLIDs_h, rLIDs);
652 auto field_h = Kokkos::create_mirror_view(field);
653 Kokkos::deep_copy(field_h, field);
655 BCFieldType::array_type::host_mirror_type applyBC_h;
657 auto applyBC =
applyBC_[fieldIndex].get_static_view();
658 applyBC_h = Kokkos::create_mirror_view(applyBC);
659 Kokkos::deep_copy(applyBC_h, applyBC);
663 for(std::size_t worksetCellIndex=0;worksetCellIndex<localCellIds.size();++worksetCellIndex) {
664 std::size_t cellLocalId = localCellIds[worksetCellIndex];
667 for(std::size_t basis=0;basis<subElmtOffset.size();basis++) {
668 int offset = subElmtOffset[basis];
669 int lid = rLIDs_h(cellLocalId, offset);
673 int basisId = subBasisIdMap[basis];
679 for(
int colIndexer=0;colIndexer<numFieldBlocks;colIndexer++) {
680 int start = blockOffsets[colIndexer];
681 int end = blockOffsets[colIndexer+1];
687 std::pair<int,int> blockIndex = std::make_pair(rowIndexer,colIndexer);
688 Teuchos::RCP<Epetra_CrsMatrix> subJac = jacEpetraBlocks[blockIndex];
690 if(subJac==Teuchos::null) {
691 Teuchos::RCP<Thyra::LinearOpBase<double> > tOp =
Jac_->getNonconstBlock(blockIndex.first,blockIndex.second);
694 if(Teuchos::is_null(tOp))
697 Teuchos::RCP<Epetra_Operator> eOp = Thyra::get_Epetra_Operator(*tOp);
698 subJac = rcp_dynamic_cast<Epetra_CrsMatrix>(eOp,
true);
699 jacEpetraBlocks[blockIndex] = subJac;
703 int * rowIndices = 0;
704 double * rowValues = 0;
706 subJac->ExtractMyRowView(lid,numEntries,rowValues,rowIndices);
708 for(
int i=0;i<numEntries;i++)
712 const ScalarT scatterField = field_h(worksetCellIndex,basisId);
714 if(
r_!=Teuchos::null)
715 local_r[lid] = scatterField.val();
719 std::vector<double> jacRow(scatterField.size(),0.0);
721 for(
int sensIndex=0;sensIndex<scatterField.size();++sensIndex)
722 jacRow[sensIndex] = scatterField.fastAccessDx(sensIndex);
724 for(
int colIndexer=0;colIndexer<numFieldBlocks;colIndexer++) {
725 int start = blockOffsets[colIndexer];
726 int end = blockOffsets[colIndexer+1];
733 auto cLIDs = subColIndexer->getElementLIDs(cellLocalId);
734 auto cLIDs_h = Kokkos::create_mirror_view(cLIDs);
735 Kokkos::deep_copy(cLIDs_h, cLIDs);
737 TEUCHOS_ASSERT(end-start==Teuchos::as<int>(cLIDs.size()));
740 std::pair<int,int> blockIndex = std::make_pair(rowIndexer,colIndexer);
741 Teuchos::RCP<Epetra_CrsMatrix> subJac = jacEpetraBlocks[blockIndex];
744 if(subJac==Teuchos::null) {
745 Teuchos::RCP<Thyra::LinearOpBase<double> > tOp =
Jac_->getNonconstBlock(blockIndex.first,blockIndex.second);
748 if(Teuchos::is_null(tOp))
751 Teuchos::RCP<Epetra_Operator> eOp = Thyra::get_Epetra_Operator(*tOp);
752 subJac = rcp_dynamic_cast<Epetra_CrsMatrix>(eOp,
true);
753 jacEpetraBlocks[blockIndex] = subJac;
757 int err = subJac->ReplaceMyValues(lid, end-start, &jacRow[start],&cLIDs_h[0]);
759 std::stringstream ss;
760 ss <<
"Failed inserting row: " <<
" (" << lid <<
"): ";
761 for(
int i=0;i<end-start;i++)
762 ss << cLIDs_h[i] <<
" ";
764 ss <<
"Into block " << rowIndexer <<
", " << colIndexer << std::endl;
766 ss <<
"scatter field = ";
770 TEUCHOS_TEST_FOR_EXCEPTION(err!=0,std::runtime_error,ss.str());