11#ifndef __Panzer_BlockedTpetraLinearObjFactory_impl_hpp__
12#define __Panzer_BlockedTpetraLinearObjFactory_impl_hpp__
17#ifdef PANZER_HAVE_EPETRA_STACK
23#include "KokkosSparse_SortCrs.hpp"
26#include "Thyra_DefaultBlockedLinearOp.hpp"
27#include "Thyra_DefaultProductVector.hpp"
28#include "Thyra_DefaultProductVectorSpace.hpp"
29#include "Thyra_SpmdVectorBase.hpp"
30#include "Thyra_TpetraLinearOp.hpp"
31#include "Thyra_TpetraThyraWrappers.hpp"
34#include "Tpetra_CrsMatrix.hpp"
35#include "Tpetra_MultiVector.hpp"
36#include "Tpetra_Vector.hpp"
46template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
49 const Teuchos::RCP<const BlockedDOFManager> & gidProvider,
51 : blockProvider_(gidProvider), blockedDOFManager_(gidProvider), hasColProvider_(false), comm_(comm)
52 , useFEAssembly_(useFEAssembly)
54 for(std::size_t i=0;i<gidProvider->getFieldDOFManagers().size();i++)
55 gidProviders_.push_back(gidProvider->getFieldDOFManagers()[i]);
64template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
67 const std::vector<Teuchos::RCP<const panzer::GlobalIndexer>> & gidProviders,
69 : gidProviders_(gidProviders), hasColProvider_(false), comm_(comm)
70 , useFEAssembly_(useFEAssembly)
75template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
78 const Teuchos::RCP<const GlobalIndexer> & rowProvider,
79 const Teuchos::RCP<const GlobalIndexer> & colProvider,
81 : blockProvider_(rowProvider), hasColProvider_(true), colBlockProvider_(colProvider), comm_(comm)
82 , useFEAssembly_(useFEAssembly)
89 "BlockedTpetraLinearObjFactory: FE assembly is not supported for a non-square "
90 "factory (one built with a separate column provider).");
102template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
105 Teuchos::RCP<const BlockedDOFManager> & blocked,
106 std::vector<Teuchos::RCP<const GlobalIndexer> > & blocks)
108 blocked = Teuchos::rcp_dynamic_cast<const BlockedDOFManager>(ugi);
111 if(blocked!=Teuchos::null) {
112 const auto & dofManagers = blocked->getFieldDOFManagers();
113 for(std::size_t i=0;i<dofManagers.size();i++)
114 blocks.push_back(dofManagers[i]);
117 TEUCHOS_TEST_FOR_EXCEPTION(ugi==Teuchos::null,std::logic_error,
118 "BlockedTpetraLinearObjFactory: a null global indexer was supplied.");
119 blocks.push_back(ugi);
123template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
131template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
132Teuchos::RCP<LinearObjContainer>
136 std::vector<Teuchos::RCP<const MapType> > blockMaps;
137 std::size_t blockDim = gidProviders_.size();
138 for(std::size_t i=0;i<blockDim;i++)
139 blockMaps.push_back(getMap(i));
141 Teuchos::RCP<BTLOC> container = Teuchos::rcp(
new BTLOC);
142 container->setMapsForBlocks(blockMaps);
147template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
148Teuchos::RCP<LinearObjContainer>
152 std::vector<Teuchos::RCP<const MapType> > blockMaps;
153 std::size_t blockDim = gidProviders_.size();
154 for(std::size_t i=0;i<blockDim;i++)
155 blockMaps.push_back(getGhostedMap(i));
157 Teuchos::RCP<BTLOC> container = Teuchos::rcp(
new BTLOC);
158 container->setMapsForBlocks(blockMaps);
163template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
167 using Teuchos::is_null;
171 const BTLOC & b_in = Teuchos::dyn_cast<const BTLOC>(in);
172 BTLOC & b_out = Teuchos::dyn_cast<BTLOC>(out);
176 if ( !is_null(b_in.
get_x()) && !is_null(b_out.
get_x()) && ((mem & LOC::X)==LOC::X))
177 globalToGhostThyraVector(b_in.
get_x(),b_out.
get_x(),
true);
179 if ( !is_null(b_in.
get_dxdt()) && !is_null(b_out.
get_dxdt()) && ((mem & LOC::DxDt)==LOC::DxDt))
182 if ( !is_null(b_in.
get_f()) && !is_null(b_out.
get_f()) && ((mem & LOC::F)==LOC::F))
183 globalToGhostThyraVector(b_in.
get_f(),b_out.
get_f(),
false);
186template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
190 using Teuchos::is_null;
194 const BTLOC & b_in = Teuchos::dyn_cast<const BTLOC>(in);
195 BTLOC & b_out = Teuchos::dyn_cast<BTLOC>(out);
199 if ( !is_null(b_in.
get_x()) && !is_null(b_out.
get_x()) && ((mem & LOC::X)==LOC::X))
200 ghostToGlobalThyraVector(b_in.
get_x(),b_out.
get_x(),
true);
202 if ( !is_null(b_in.
get_f()) && !is_null(b_out.
get_f()) && ((mem & LOC::F)==LOC::F))
203 ghostToGlobalThyraVector(b_in.
get_f(),b_out.
get_f(),
false);
205 if ( !is_null(b_in.
get_A()) && !is_null(b_out.
get_A()) && ((mem & LOC::Mat)==LOC::Mat))
206 ghostToGlobalThyraMatrix(*b_in.
get_A(),*b_out.
get_A());
209template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
214 bool zeroVectorRows,
bool adjustX)
const
217 using Teuchos::rcp_dynamic_cast;
219 using Thyra::PhysicallyBlockedLinearOpBase;
225 std::size_t blockDim = getBlockRowCount();
226 std::size_t colBlockDim = getBlockColCount();
229 const BTLOC & b_localBCRows = Teuchos::dyn_cast<const BTLOC>(localBCRows);
230 const BTLOC & b_globalBCRows = Teuchos::dyn_cast<const BTLOC>(globalBCRows);
231 BTLOC & b_ghosted = Teuchos::dyn_cast<BTLOC>(ghostedObjs);
233 TEUCHOS_ASSERT(b_localBCRows.
get_f()!=Teuchos::null);
234 TEUCHOS_ASSERT(b_globalBCRows.
get_f()!=Teuchos::null);
237 RCP<PhysicallyBlockedLinearOpBase<ScalarT> > A = rcp_dynamic_cast<PhysicallyBlockedLinearOpBase<ScalarT> >(b_ghosted.
get_A());
238 RCP<ProductVectorBase<ScalarT> > f = rcp_dynamic_cast<ProductVectorBase<ScalarT> >(b_ghosted.
get_f());
239 RCP<ProductVectorBase<ScalarT> > local_bcs = rcp_dynamic_cast<ProductVectorBase<ScalarT> >(b_localBCRows.
get_f(),
true);
240 RCP<ProductVectorBase<ScalarT> > global_bcs = rcp_dynamic_cast<ProductVectorBase<ScalarT> >(b_globalBCRows.
get_f(),
true);
242 if(adjustX) f = rcp_dynamic_cast<ProductVectorBase<ScalarT> >(b_ghosted.
get_x());
245 if(A!=Teuchos::null) TEUCHOS_ASSERT(A->productRange()->numBlocks()==(
int) blockDim);
246 if(A!=Teuchos::null) TEUCHOS_ASSERT(A->productDomain()->numBlocks()==(
int) colBlockDim);
247 if(f!=Teuchos::null) TEUCHOS_ASSERT(f->productSpace()->numBlocks()==(
int) blockDim);
248 TEUCHOS_ASSERT(local_bcs->productSpace()->numBlocks()==(
int) blockDim);
249 TEUCHOS_ASSERT(global_bcs->productSpace()->numBlocks()==(
int) blockDim);
251 for(std::size_t i=0;i<blockDim;i++) {
253 RCP<const VectorType> t_local_bcs = rcp_dynamic_cast<const ThyraVector>(local_bcs->getVectorBlock(i),
true)->getConstTpetraVector();
254 RCP<const VectorType> t_global_bcs = rcp_dynamic_cast<const ThyraVector>(global_bcs->getVectorBlock(i),
true)->getConstTpetraVector();
257 RCP<VectorBase<ScalarT> > th_f = (f==Teuchos::null) ? Teuchos::null : f->getNonconstVectorBlock(i);
259 if(th_f==Teuchos::null)
262 t_f = rcp_dynamic_cast<ThyraVector>(th_f,
true)->getTpetraVector();
264 for(std::size_t j=0;j<colBlockDim;j++) {
265 RCP<const MapType> map_i = getGhostedMap(i);
266 RCP<const MapType> map_j = getGhostedColMap(j);
269 RCP<LinearOpBase<ScalarT> > th_A = (A== Teuchos::null)? Teuchos::null : A->getNonconstBlock(i,j);
272 RCP<CrsMatrixType> t_A;
273 if(th_A==Teuchos::null)
276 RCP<OperatorType> t_A_op = rcp_dynamic_cast<ThyraLinearOp>(th_A,
true)->getTpetraOperator();
277 t_A = rcp_dynamic_cast<CrsMatrixType>(t_A_op,
true);
281 if(t_A!=Teuchos::null) {
285 adjustForDirichletConditions(*t_local_bcs,*t_global_bcs,t_f.ptr(),t_A.ptr(),zeroVectorRows);
287 if(t_A!=Teuchos::null) {
296template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
300 const Teuchos::Ptr<VectorType> & f,
301 const Teuchos::Ptr<CrsMatrixType> & A,
302 bool zeroVectorRows)
const
304 if(f==Teuchos::null && A==Teuchos::null)
307 Teuchos::ArrayRCP<ScalarT> f_array = f!=Teuchos::null ? f->get1dViewNonConst() : Teuchos::null;
309 Teuchos::ArrayRCP<const ScalarT> local_bcs_array = local_bcs.get1dView();
310 Teuchos::ArrayRCP<const ScalarT> global_bcs_array = global_bcs.get1dView();
312 TEUCHOS_ASSERT(local_bcs.getLocalLength()==global_bcs.getLocalLength());
313 for(std::size_t i=0;i<local_bcs.getLocalLength();i++) {
314 if(global_bcs_array[i]==0.0)
317 if(local_bcs_array[i]==0.0 || zeroVectorRows) {
321 if(!Teuchos::is_null(f))
323 if(!Teuchos::is_null(A)) {
324 std::size_t numEntries = 0;
325 std::size_t sz = A->getNumEntriesInLocalRow(i);
326 typename CrsMatrixType::nonconst_local_inds_host_view_type indices(
"indices", sz);
327 typename CrsMatrixType::nonconst_values_host_view_type values(
"values", sz);
329 A->getLocalRowCopy(i,indices,values,numEntries);
331 for(std::size_t c=0;c<numEntries;c++)
334 A->replaceLocalValues(i,indices,values);
340 ScalarT scaleFactor = global_bcs_array[i];
343 if(!Teuchos::is_null(f))
344 f_array[i] /= scaleFactor;
345 if(!Teuchos::is_null(A)) {
346 std::size_t numEntries = 0;
347 std::size_t sz = A->getNumEntriesInLocalRow(i);
348 typename CrsMatrixType::nonconst_local_inds_host_view_type indices(
"indices", sz);
349 typename CrsMatrixType::nonconst_values_host_view_type values(
"values", sz);
351 A->getLocalRowCopy(i,indices,values,numEntries);
353 for(std::size_t c=0;c<numEntries;c++)
354 values(c) /= scaleFactor;
356 A->replaceLocalValues(i,indices,values);
362template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
367 TEUCHOS_ASSERT(
false);
375template<
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
376 typename GlobalOrdinalT,
typename NodeT>
377Teuchos::RCP<ReadOnlyVector_GlobalEvaluationData>
380buildReadOnlyDomainContainer()
const
387 LocalOrdinalT, GlobalOrdinalT, NodeT>;
391 if (hasColProvider_ and colBlockedDOFManager_.is_null())
393 auto tvroged = rcp(
new TVROGED);
394 tvroged->initialize(getGhostedColImport(0), getGhostedColMap(0), getColMap(0));
398 vector<RCP<ReadOnlyVector_GlobalEvaluationData>> gedBlocks;
399 for (
int i(0); i < getBlockColCount(); ++i)
401 auto tvroged = rcp(
new TVROGED);
402 tvroged->initialize(getGhostedColImport(i), getGhostedColMap(i), getColMap(i));
403 gedBlocks.push_back(tvroged);
405 auto ged = rcp(
new BVROGED);
406 ged->initialize(getGhostedThyraDomainSpace(), getThyraDomainSpace(),
411#ifdef PANZER_HAVE_EPETRA_STACK
417template<
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
418 typename GlobalOrdinalT,
typename NodeT>
419Teuchos::RCP<WriteVector_GlobalEvaluationData>
422buildWriteDomainContainer()
const
424 using std::logic_error;
427 auto ged = rcp(
new EVWGED);
428 TEUCHOS_TEST_FOR_EXCEPTION(
true, logic_error,
"NOT YET IMPLEMENTED")
433template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
440template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
444 BTLOC & bloc = Teuchos::dyn_cast<BTLOC>(loc);
445 initializeContainer(mem,bloc);
448template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
452 BTLOC & bloc = Teuchos::dyn_cast<BTLOC>(loc);
453 initializeGhostedContainer(mem,bloc);
459template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
467 if((mem & LOC::X) == LOC::X)
468 loc.
set_x(getThyraDomainVector());
470 if((mem & LOC::DxDt) == LOC::DxDt)
471 loc.
set_dxdt(getThyraDomainVector());
473 if((mem & LOC::F) == LOC::F)
474 loc.
set_f(getThyraRangeVector());
476 if((mem & LOC::Mat) == LOC::Mat)
477 loc.
set_A(getThyraMatrix());
480template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
488 if((mem & LOC::X) == LOC::X)
489 loc.
set_x(getGhostedThyraDomainVector());
491 if((mem & LOC::DxDt) == LOC::DxDt)
492 loc.
set_dxdt(getGhostedThyraDomainVector());
494 if((mem & LOC::F) == LOC::F) {
495 loc.
set_f(getGhostedThyraRangeVector());
499 if((mem & LOC::Mat) == LOC::Mat) {
503 loc.
set_A(getGhostedThyraMatrix());
508template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
512 excludedPairs_.insert(std::make_pair(rowBlock,colBlock));
515template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
519 for(std::size_t i=0;i<exPairs.size();i++)
520 excludedPairs_.insert(exPairs[i]);
523template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
524Teuchos::RCP<const GlobalIndexer>
528 return gidProviders_[i];
531template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
532Teuchos::RCP<const GlobalIndexer>
536 return hasColProvider_ ? colGidProviders_[i] : gidProviders_[i];
539template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
543 maps_.resize(blockCnt);
544 ghostedMaps_.resize(blockCnt);
545 importers_.resize(blockCnt);
546 exporters_.resize(blockCnt);
549 colMaps_.resize(colBlockCnt);
550 ghostedColMaps_.resize(colBlockCnt);
551 colImporters_.resize(colBlockCnt);
552 colExporters_.resize(colBlockCnt);
559template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
560Teuchos::RCP<const Thyra::VectorSpaceBase<ScalarT> >
564 if(domainSpace_==Teuchos::null) {
565 if(hasColProvider_ and colBlockedDOFManager_.is_null()) {
567 domainSpace_ = Thyra::createVectorSpace<ScalarT,LocalOrdinalT,GlobalOrdinalT,NodeT>(getColMap(0));
571 std::vector<Teuchos::RCP<const Thyra::VectorSpaceBase<ScalarT> > > vsArray;
572 for(
int i=0;i<getBlockColCount();i++)
573 vsArray.push_back(Thyra::createVectorSpace<ScalarT,LocalOrdinalT,GlobalOrdinalT,NodeT>(getColMap(i)));
575 domainSpace_ = Thyra::productVectorSpace<ScalarT>(vsArray);
582template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
583Teuchos::RCP<const Thyra::VectorSpaceBase<ScalarT> >
587 if(rangeSpace_==Teuchos::null) {
589 std::vector<Teuchos::RCP<const Thyra::VectorSpaceBase<ScalarT> > > vsArray;
590 for(std::size_t i=0;i<gidProviders_.size();i++)
591 vsArray.push_back(Thyra::createVectorSpace<ScalarT,LocalOrdinalT,GlobalOrdinalT,NodeT>(getMap(i)));
593 rangeSpace_ = Thyra::productVectorSpace<ScalarT>(vsArray);
599template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
600Teuchos::RCP<const Thyra::VectorSpaceBase<ScalarT> >
604 if(domainSpace_==Teuchos::null) {
605 getThyraDomainSpace();
608 auto prod_space = Teuchos::rcp_dynamic_cast<const Thyra::ProductVectorSpaceBase<ScalarT> >(domainSpace_);
609 if(prod_space==Teuchos::null) {
611 TEUCHOS_ASSERT(blk==0);
615 return prod_space->getBlock(blk);
618template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
619Teuchos::RCP<const Thyra::VectorSpaceBase<ScalarT> >
623 if(rangeSpace_==Teuchos::null) {
624 getThyraRangeSpace();
627 return rangeSpace_->getBlock(blk);
630template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
631Teuchos::RCP<Thyra::VectorBase<ScalarT> >
635 Teuchos::RCP<Thyra::VectorBase<ScalarT> > vec =
636 Thyra::createMember<ScalarT>(*getThyraDomainSpace());
637 Thyra::assign(vec.ptr(),0.0);
642 using ThyraTpetraVector = Thyra::TpetraVector<ScalarT,LocalOrdinalT,GlobalOrdinalT,NodeT>;
643 Teuchos::RCP<Thyra::ProductVectorBase<ScalarT> > p_vec = Teuchos::rcp_dynamic_cast<Thyra::ProductVectorBase<ScalarT> >(vec);
644 if(p_vec==Teuchos::null) {
645 TEUCHOS_ASSERT(getBlockColCount()==1);
646 auto tp_vec = Teuchos::rcp_dynamic_cast<ThyraTpetraVector>(vec,
true)->getTpetraVector();
647 TEUCHOS_ASSERT(tp_vec->getLocalLength()==getColMap(0)->getLocalNumElements());
650 for(
int i=0;i<getBlockColCount();i++) {
651 auto tp_blk = Teuchos::rcp_dynamic_cast<ThyraTpetraVector>(p_vec->getNonconstVectorBlock(i),
true)->getTpetraVector();
652 TEUCHOS_ASSERT(tp_blk->getLocalLength()==getColMap(i)->getLocalNumElements());
659template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
660Teuchos::RCP<Thyra::VectorBase<ScalarT> >
664 Teuchos::RCP<Thyra::VectorBase<ScalarT> > vec =
665 Thyra::createMember<ScalarT>(*getThyraRangeSpace());
666 Thyra::assign(vec.ptr(),0.0);
671template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
672Teuchos::RCP<Thyra::LinearOpBase<ScalarT> >
676 Teuchos::RCP<Thyra::PhysicallyBlockedLinearOpBase<ScalarT> > blockedOp = Thyra::defaultBlockedLinearOp<ScalarT>();
679 std::size_t rowBlockDim = getBlockRowCount();
680 std::size_t colBlockDim = getBlockColCount();
682 blockedOp->beginBlockFill(rowBlockDim,colBlockDim);
685 for(std::size_t i=0;i<rowBlockDim;i++) {
686 for(std::size_t j=0;j<colBlockDim;j++) {
687 if(excludedPairs_.find(std::make_pair(i,j))==excludedPairs_.end()) {
696 Teuchos::RCP<Thyra::LinearOpBase<ScalarT> > block;
698 block = Thyra::tpetraLinearOp<ScalarT,LocalOrdinalT,GlobalOrdinalT,NodeT>(
699 getThyraRangeSpace(i),getThyraDomainSpace(j),getTpetraMatrix(i,j));
701 block = Thyra::createLinearOp<ScalarT,LocalOrdinalT,GlobalOrdinalT,NodeT>(getTpetraMatrix(i,j));
702 blockedOp->setNonconstBlock(i,j,block);
708 blockedOp->endBlockFill();
713template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
714Teuchos::RCP<const Thyra::VectorSpaceBase<ScalarT> >
718 if(ghostedDomainSpace_==Teuchos::null) {
719 if(hasColProvider_ and colBlockedDOFManager_.is_null()) {
721 ghostedDomainSpace_ = Thyra::createVectorSpace<ScalarT,LocalOrdinalT,GlobalOrdinalT,NodeT>(getGhostedColMap(0));
725 std::vector<Teuchos::RCP<const Thyra::VectorSpaceBase<ScalarT> > > vsArray;
726 for(
int i=0;i<getBlockColCount();i++)
727 vsArray.push_back(Thyra::createVectorSpace<ScalarT,LocalOrdinalT,GlobalOrdinalT,NodeT>(getGhostedColMap(i)));
729 ghostedDomainSpace_ = Thyra::productVectorSpace<ScalarT>(vsArray);
733 return ghostedDomainSpace_;
736template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
737Teuchos::RCP<const Thyra::VectorSpaceBase<ScalarT> >
741 if(ghostedRangeSpace_==Teuchos::null) {
743 std::vector<Teuchos::RCP<const Thyra::VectorSpaceBase<ScalarT> > > vsArray;
744 for(std::size_t i=0;i<gidProviders_.size();i++)
745 vsArray.push_back(Thyra::createVectorSpace<ScalarT,LocalOrdinalT,GlobalOrdinalT,NodeT>(getGhostedMap(i)));
747 ghostedRangeSpace_ = Thyra::productVectorSpace<ScalarT>(vsArray);
750 return ghostedRangeSpace_;
753template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
754Teuchos::RCP<Thyra::VectorBase<ScalarT> >
758 Teuchos::RCP<Thyra::VectorBase<ScalarT> > vec =
759 Thyra::createMember<ScalarT>(*getGhostedThyraDomainSpace());
760 Thyra::assign(vec.ptr(),0.0);
765template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
766Teuchos::RCP<Thyra::VectorBase<ScalarT> >
770 Teuchos::RCP<Thyra::VectorBase<ScalarT> > vec =
771 Thyra::createMember<ScalarT>(*getGhostedThyraRangeSpace());
772 Thyra::assign(vec.ptr(),0.0);
777template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
778Teuchos::RCP<Thyra::BlockedLinearOpBase<ScalarT> >
783 TEUCHOS_TEST_FOR_EXCEPTION(useFEAssembly_,std::logic_error,
784 "BlockedTpetraLinearObjFactory::getGhostedThyraMatrix: not available under FE "
785 "assembly. The ghosted container shares the owned container's operator, which is "
786 "connected by beginFill(ghosted,owned); use getThyraMatrix() to allocate one.");
788 Teuchos::RCP<Thyra::PhysicallyBlockedLinearOpBase<ScalarT> > blockedOp = Thyra::defaultBlockedLinearOp<ScalarT>();
791 std::size_t rowBlockDim = getBlockRowCount();
792 std::size_t colBlockDim = getBlockColCount();
794 blockedOp->beginBlockFill(rowBlockDim,colBlockDim);
797 for(std::size_t i=0;i<rowBlockDim;i++) {
798 for(std::size_t j=0;j<colBlockDim;j++) {
799 if(excludedPairs_.find(std::make_pair(i,j))==excludedPairs_.end()) {
801 Teuchos::RCP<Thyra::LinearOpBase<ScalarT> > block
802 = Thyra::createLinearOp<ScalarT,LocalOrdinalT,GlobalOrdinalT,NodeT>(getGhostedTpetraMatrix(i,j));
803 blockedOp->setNonconstBlock(i,j,block);
809 blockedOp->endBlockFill();
814template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
820 using Teuchos::rcp_dynamic_cast;
823 std::size_t blockDim = col ? getBlockColCount() : getBlockRowCount();
826 RCP<const ProductVectorBase<ScalarT> > prod_in = Thyra::castOrCreateProductVectorBase(in);
827 RCP<ProductVectorBase<ScalarT> > prod_out = Thyra::castOrCreateNonconstProductVectorBase(out);
829 TEUCHOS_ASSERT(prod_in->productSpace()->numBlocks()==(
int) blockDim);
830 TEUCHOS_ASSERT(prod_out->productSpace()->numBlocks()==(
int) blockDim);
832 for(std::size_t i=0;i<blockDim;i++) {
834 RCP<const VectorType> tp_in = rcp_dynamic_cast<const ThyraVector>(prod_in->getVectorBlock(i),
true)->getConstTpetraVector();
835 RCP<VectorType> tp_out = rcp_dynamic_cast<ThyraVector>(prod_out->getNonconstVectorBlock(i),
true)->getTpetraVector();
838 ghostToGlobalTpetraVector(i,*tp_in,*tp_out,col);
842template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
847 using Teuchos::rcp_dynamic_cast;
848 using Teuchos::dyn_cast;
850 using Thyra::PhysicallyBlockedLinearOpBase;
852 std::size_t rowBlockDim = getBlockRowCount();
855 const PhysicallyBlockedLinearOpBase<ScalarT> & prod_in = dyn_cast<const PhysicallyBlockedLinearOpBase<ScalarT> >(in);
856 PhysicallyBlockedLinearOpBase<ScalarT> & prod_out = dyn_cast<PhysicallyBlockedLinearOpBase<ScalarT> >(out);
858 std::size_t colBlockDim = getBlockColCount();
860 TEUCHOS_ASSERT(prod_in.productRange()->numBlocks()==(
int) rowBlockDim);
861 TEUCHOS_ASSERT(prod_in.productDomain()->numBlocks()==(
int) colBlockDim);
862 TEUCHOS_ASSERT(prod_out.productRange()->numBlocks()==(
int) rowBlockDim);
863 TEUCHOS_ASSERT(prod_out.productDomain()->numBlocks()==(
int) colBlockDim);
865 for(std::size_t i=0;i<rowBlockDim;i++) {
866 for(std::size_t j=0;j<colBlockDim;j++) {
867 if(excludedPairs_.find(std::make_pair(i,j))==excludedPairs_.end()) {
869 RCP<const LinearOpBase<ScalarT> > th_in = prod_in.getBlock(i,j);
870 RCP<LinearOpBase<ScalarT> > th_out = prod_out.getNonconstBlock(i,j);
873 TEUCHOS_ASSERT(th_in!=Teuchos::null);
874 TEUCHOS_ASSERT(th_out!=Teuchos::null);
877 RCP<const OperatorType> tp_op_in = rcp_dynamic_cast<const ThyraLinearOp>(th_in,
true)->getConstTpetraOperator();
878 RCP<OperatorType> tp_op_out = rcp_dynamic_cast<ThyraLinearOp>(th_out,
true)->getTpetraOperator();
880 RCP<const CrsMatrixType> tp_in = rcp_dynamic_cast<const CrsMatrixType>(tp_op_in,
true);
881 RCP<CrsMatrixType> tp_out = rcp_dynamic_cast<CrsMatrixType>(tp_op_out,
true);
891 if(tp_in.get()==tp_out.get())
895 ghostToGlobalTpetraMatrix(i,*tp_in,*tp_out);
901template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
907 using Teuchos::rcp_dynamic_cast;
910 std::size_t blockDim = col ? getBlockColCount() : getBlockRowCount();
913 RCP<const ProductVectorBase<ScalarT> > prod_in = Thyra::castOrCreateProductVectorBase(in);
914 RCP<ProductVectorBase<ScalarT> > prod_out = Thyra::castOrCreateNonconstProductVectorBase(out);
916 TEUCHOS_ASSERT(prod_in->productSpace()->numBlocks()==(
int) blockDim);
917 TEUCHOS_ASSERT(prod_out->productSpace()->numBlocks()==(
int) blockDim);
919 for(std::size_t i=0;i<blockDim;i++) {
921 RCP<const VectorType> tp_in = rcp_dynamic_cast<const ThyraVector>(prod_in->getVectorBlock(i),
true)->getConstTpetraVector();
922 RCP<VectorType> tp_out = rcp_dynamic_cast<ThyraVector>(prod_out->getNonconstVectorBlock(i),
true)->getTpetraVector();
925 globalToGhostTpetraVector(i,*tp_in,*tp_out,col);
932template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
939 RCP<const ExportType> exporter = col ? getGhostedColExport(i) : getGhostedExport(i);
941 out.doExport(in,*exporter,Tpetra::ADD);
944template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
950 RCP<const MapType> map_i = out.getRangeMap();
951 RCP<const MapType> map_j = out.getDomainMap();
954 RCP<const ExportType> exporter = getGhostedExport(blockRow);
957 out.setAllToScalar(0.0);
958 out.doExport(in,*exporter,Tpetra::ADD);
959 out.fillComplete(map_j,map_i);
962template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
969 RCP<const ImportType> importer = col ? getGhostedColImport(i) : getGhostedImport(i);
971 out.doImport(in,*importer,Tpetra::INSERT);
975template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
976Teuchos::RCP<const Tpetra::Map<LocalOrdinalT,GlobalOrdinalT,NodeT> >
980 if(maps_[i]==Teuchos::null)
981 maps_[i] = buildTpetraMap(i);
986template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
987Teuchos::RCP<const Tpetra::Map<LocalOrdinalT,GlobalOrdinalT,NodeT> >
991 if(ghostedMaps_[i]==Teuchos::null)
992 ghostedMaps_[i] = buildTpetraGhostedMap(i);
994 return ghostedMaps_[i];
998template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
999Teuchos::RCP<const Tpetra::CrsGraph<LocalOrdinalT,GlobalOrdinalT,NodeT> >
1003 typedef std::unordered_map<std::pair<int,int>,Teuchos::RCP<const CrsGraphType>,
panzer::pair_hash> GraphMap;
1005 typename GraphMap::const_iterator itr = graphs_.find(std::make_pair(i,j));
1006 Teuchos::RCP<const CrsGraphType> graph;
1007 if(itr==graphs_.end()) {
1008 graph = buildTpetraGraph(i,j);
1009 graphs_[std::make_pair(i,j)] = graph;
1012 graph = itr->second;
1014 TEUCHOS_ASSERT(graph!=Teuchos::null);
1018template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
1019Teuchos::RCP<const Tpetra::CrsGraph<LocalOrdinalT,GlobalOrdinalT,NodeT> >
1023 typedef std::unordered_map<std::pair<int,int>,Teuchos::RCP<const CrsGraphType>,
panzer::pair_hash> GraphMap;
1025 typename GraphMap::const_iterator itr = ghostedGraphs_.find(std::make_pair(i,j));
1026 Teuchos::RCP<const CrsGraphType> ghostedGraph;
1027 if(itr==ghostedGraphs_.end()) {
1028 ghostedGraph = buildTpetraGhostedGraph(i,j);
1029 ghostedGraphs_[std::make_pair(i,j)] = ghostedGraph;
1032 ghostedGraph = itr->second;
1034 TEUCHOS_ASSERT(ghostedGraph!=Teuchos::null);
1035 return ghostedGraph;
1038template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
1039Teuchos::RCP<const Tpetra::Import<LocalOrdinalT,GlobalOrdinalT,NodeT> >
1043 if(importers_[i]==Teuchos::null)
1044 importers_[i] = Teuchos::rcp(
new ImportType(getMap(i),getGhostedMap(i)));
1046 return importers_[i];
1049template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
1050Teuchos::RCP<const Tpetra::Export<LocalOrdinalT,GlobalOrdinalT,NodeT> >
1054 if(exporters_[i]==Teuchos::null)
1055 exporters_[i] = Teuchos::rcp(
new ExportType(getGhostedMap(i),getMap(i)));
1057 return exporters_[i];
1060template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
1061Teuchos::RCP<const Tpetra::Map<LocalOrdinalT,GlobalOrdinalT,NodeT> >
1065 if(!hasColProvider_)
1068 if(colMaps_[i]==Teuchos::null)
1069 colMaps_[i] = buildColTpetraMap(i);
1074template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
1075Teuchos::RCP<const Tpetra::Map<LocalOrdinalT,GlobalOrdinalT,NodeT> >
1079 if(!hasColProvider_)
1080 return getGhostedMap(i);
1082 if(ghostedColMaps_[i]==Teuchos::null)
1083 ghostedColMaps_[i] = buildColTpetraGhostedMap(i);
1085 return ghostedColMaps_[i];
1088template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
1089Teuchos::RCP<const Tpetra::Import<LocalOrdinalT,GlobalOrdinalT,NodeT> >
1093 if(!hasColProvider_)
1094 return getGhostedImport(i);
1096 if(colImporters_[i]==Teuchos::null)
1097 colImporters_[i] = Teuchos::rcp(
new ImportType(getColMap(i),getGhostedColMap(i)));
1099 return colImporters_[i];
1102template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
1103Teuchos::RCP<const Tpetra::Export<LocalOrdinalT,GlobalOrdinalT,NodeT> >
1107 if(!hasColProvider_)
1108 return getGhostedExport(i);
1110 if(colExporters_[i]==Teuchos::null)
1111 colExporters_[i] = Teuchos::rcp(
new ExportType(getGhostedColMap(i),getColMap(i)));
1113 return colExporters_[i];
1116template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
1117Teuchos::RCP<const Tpetra::Map<LocalOrdinalT,GlobalOrdinalT,NodeT> >
1121 std::vector<GlobalOrdinalT> indices;
1124 getGlobalIndexer(i)->getOwnedIndices(indices);
1126 return Teuchos::rcp(
new MapType(Teuchos::OrdinalTraits<GlobalOrdinalT>::invalid(),indices,0,comm_));
1130template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
1131Teuchos::RCP<const Tpetra::Map<LocalOrdinalT,GlobalOrdinalT,NodeT> >
1135 std::vector<GlobalOrdinalT> indices;
1138 getGlobalIndexer(i)->getOwnedAndGhostedIndices(indices);
1140 return Teuchos::rcp(
new MapType(Teuchos::OrdinalTraits<GlobalOrdinalT>::invalid(),indices,0,comm_));
1143template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
1144Teuchos::RCP<const Tpetra::Map<LocalOrdinalT,GlobalOrdinalT,NodeT> >
1148 std::vector<GlobalOrdinalT> indices;
1151 getColGlobalIndexer(i)->getOwnedIndices(indices);
1153 return Teuchos::rcp(
new MapType(Teuchos::OrdinalTraits<GlobalOrdinalT>::invalid(),indices,0,comm_));
1156template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
1157Teuchos::RCP<const Tpetra::Map<LocalOrdinalT,GlobalOrdinalT,NodeT> >
1161 std::vector<GlobalOrdinalT> indices;
1164 getColGlobalIndexer(i)->getOwnedAndGhostedIndices(indices);
1166 return Teuchos::rcp(
new MapType(Teuchos::OrdinalTraits<GlobalOrdinalT>::invalid(),indices,0,comm_));
1170template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
1171Teuchos::RCP<const Tpetra::CrsGraph<LocalOrdinalT,GlobalOrdinalT,NodeT> >
1180 RCP<const MapType> map_i = getMap(i);
1181 RCP<const MapType> map_j = getColMap(j);
1183 RCP<CrsGraphType> graph = rcp(
new CrsGraphType(map_i,0));
1184 RCP<const CrsGraphType> oGraph = getGhostedGraph(i,j);
1187 RCP<const ExportType> exporter = getGhostedExport(i);
1188 graph->doExport( *oGraph, *exporter, Tpetra::INSERT );
1189 graph->fillComplete(map_j,map_i);
1194template <
class LocalOrdinalT>
1200template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
1201Teuchos::RCP<const Tpetra::CrsGraph<LocalOrdinalT,GlobalOrdinalT,NodeT> >
1205 PANZER_FUNC_TIME_MONITOR_DIFF(
"panzer::BlockedTpetraLinearObjFactory::buildTpetraGhostedGraph",BTLOF);
1209 using exec_space =
typename CrsGraphType::execution_space;
1210 using memory_space =
typename NodeT::memory_space;
1214 RCP<const MapType> map_i = getGhostedMap(i);
1215 RCP<const MapType> map_j = getGhostedColMap(j);
1217 std::vector<std::string> elementBlockIds;
1219 Teuchos::RCP<const GlobalIndexer> rowProvider, colProvider;
1221 rowProvider = getGlobalIndexer(i);
1222 colProvider = getColGlobalIndexer(j);
1224 gidProviders_[0]->getElementBlockIds(elementBlockIds);
1227 RCP<CrsGraphType> graph;
1228 if constexpr (NodeT::is_gpu) {
1232 Kokkos::View<LocalOrdinalT *, memory_space> elementsFromBlocks;
1234 auto numElementBlocks = elementBlockIds.size();
1236 std::vector<size_t> elementBlockOffsets(numElementBlocks + 1);
1237 elementBlockOffsets[0] = 0;
1241 std::vector<std::string>::const_iterator blockItr;
1242 for (blockItr = elementBlockIds.begin();
1243 blockItr != elementBlockIds.end(); ++blockItr) {
1244 std::string blockId = *blockItr;
1245 const std::vector<LocalOrdinalT> &elements =
1246 gidProviders_[0]->getElementBlock(
1249 numElements += elements.size();
1251 elementBlockOffsets[blockNo] = numElements;
1253 elementsFromBlocks = Kokkos::View<LocalOrdinalT *, memory_space>(
1254 "elementsFromBlocks", numElements);
1256 for (blockItr = elementBlockIds.begin();
1257 blockItr != elementBlockIds.end(); ++blockItr) {
1258 std::string blockId = *blockItr;
1259 const std::vector<LocalOrdinalT> &elements =
1260 gidProviders_[0]->getElementBlock(
1263 Kokkos::View<
const LocalOrdinalT *, Kokkos::HostSpace,
1264 Kokkos::MemoryTraits<Kokkos::Unmanaged>>
1265 elements_h(elements.data(), elements.size());
1269 Kokkos::make_pair(elementBlockOffsets[blockNo],
1270 elementBlockOffsets[blockNo + 1])),
1278 using local_graph_type =
typename CrsGraphType::local_graph_device_type;
1280 typename local_graph_type::row_map_type::non_const_type;
1282 typename local_graph_type::entries_type::non_const_type;
1284 using entries_map_type =
1285 Kokkos::UnorderedMap<entry_type<LocalOrdinalT>, void, exec_space>;
1287 auto numRows = map_i->getLocalNumElements();
1291 rowptr_type rowptr(
"ghostedGraph_rowptr", numRows + 2);
1293 auto rowLIDs = rowProvider->getLIDs();
1294 auto colLIDs = colProvider->getLIDs();
1296 auto numDoFsPerElementRow = rowLIDs.extent(1);
1297 auto numDoFsPerElementCol = colLIDs.extent(1);
1300 numElements * numDoFsPerElementRow * numDoFsPerElementCol;
1301 entries_map_type entries(capacity);
1307 Kokkos::parallel_for(
1308 "collect_entries", Kokkos::RangePolicy<exec_space>(0, numElements),
1309 KOKKOS_LAMBDA(
const LocalOrdinalT k) {
1310 auto elementId = elementsFromBlocks(k);
1312 for (
size_t dofNoRow = 0; dofNoRow < numDoFsPerElementRow;
1314 entry.
row = rowLIDs(elementId, dofNoRow);
1315 for (
size_t dofNoCol = 0; dofNoCol < numDoFsPerElementCol;
1317 entry.
col = colLIDs(elementId, dofNoCol);
1318 auto result = entries.insert(entry);
1321 Kokkos::atomic_inc(&rowptr(entry.
row + 2));
1327 if (!entries.failed_insert()) {
1328 auto numEntries = entries.size();
1334 typename rowptr_type::value_type numEntries2;
1335 Kokkos::parallel_scan(
1336 "prefix_sum", Kokkos::RangePolicy<exec_space>(0, numRows + 2),
1337 KOKKOS_LAMBDA(
const size_t rlid,
1338 typename rowptr_type::value_type &nnz,
1339 const bool is_final) {
1340 nnz += rowptr(rlid);
1345 TEUCHOS_ASSERT_EQUALITY(numEntries, numEntries2);
1349 Kokkos::ViewAllocateWithoutInitializing(
"ghostedGraph_colidx"),
1355 Kokkos::parallel_for(
1356 "fill", Kokkos::RangePolicy<exec_space>(0, entries.capacity()),
1357 KOKKOS_LAMBDA(
const uint32_t c) {
1358 if (entries.valid_at(c)) {
1359 auto entry = entries.key_at(c);
1361 Kokkos::atomic_fetch_inc(&rowptr(entry.row + 1));
1362 colidx(offset) = entry.col;
1367 KokkosSparse::sort_crs_graph(rowptr, colidx);
1372 Kokkos::subview(rowptr, Kokkos::make_pair((
decltype(numRows))0,
1375 graph->fillComplete(getMap(j), getMap(i));
1381 std::cout <<
"Insufficient capacity: " << capacity << std::endl;
1383 Kokkos::deep_copy(rowptr, 0);
1384 entries = entries_map_type(capacity);
1391 std::vector<size_t> nEntriesPerRow(map_i->getLocalNumElements(), 0);
1392 std::vector<std::string>::const_iterator blockItr;
1393 for (blockItr = elementBlockIds.begin(); blockItr != elementBlockIds.end();
1395 std::string blockId = *blockItr;
1397 const std::vector<LocalOrdinalT> &elements =
1398 gidProviders_[0]->getElementBlock(
1403 std::vector<GlobalOrdinalT> row_gids;
1404 std::vector<GlobalOrdinalT> col_gids;
1407 for (std::size_t elmt = 0; elmt < elements.size(); elmt++) {
1409 rowProvider->getElementGIDs(elements[elmt], row_gids);
1410 colProvider->getElementGIDs(elements[elmt], col_gids);
1411 for (std::size_t row = 0; row < row_gids.size(); row++) {
1412 LocalOrdinalT lid = map_i->getLocalElement(row_gids[row]);
1413 nEntriesPerRow[lid] += col_gids.size();
1417 Teuchos::ArrayView<const size_t> nEntriesPerRowView(nEntriesPerRow);
1418 graph = rcp(
new CrsGraphType(map_i, map_j, nEntriesPerRowView));
1421 for (blockItr = elementBlockIds.begin(); blockItr != elementBlockIds.end();
1423 std::string blockId = *blockItr;
1426 const std::vector<LocalOrdinalT> &elements =
1427 gidProviders_[0]->getElementBlock(
1432 std::vector<GlobalOrdinalT> row_gids;
1433 std::vector<GlobalOrdinalT> col_gids;
1436 for (std::size_t elmt = 0; elmt < elements.size(); elmt++) {
1438 rowProvider->getElementGIDs(elements[elmt], row_gids);
1439 colProvider->getElementGIDs(elements[elmt], col_gids);
1440 for (std::size_t row = 0; row < row_gids.size(); row++)
1441 graph->insertGlobalIndices(row_gids[row], col_gids);
1447 graph->fillComplete(getMap(j), getMap(i));
1468template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
1469Teuchos::RCP<typename BlockedTpetraLinearObjFactory<Traits,ScalarT,LocalOrdinalT,GlobalOrdinalT,NodeT>::FECrsGraphType>
1482 RCP<const MapType> ownedRowMap = getMap(i);
1483 RCP<const MapType> ownedPlusSharedRowMap = getGhostedMap(i);
1484 RCP<const MapType> ownedDomainMap = getMap(j);
1485 RCP<const MapType> ownedPlusSharedDomainMap = getGhostedMap(j);
1487 RCP<const GlobalIndexer> rowProvider = getGlobalIndexer(i);
1488 RCP<const GlobalIndexer> colProvider = getGlobalIndexer(j);
1490 std::vector<std::string> elementBlockIds;
1491 gidProviders_[0]->getElementBlockIds(elementBlockIds);
1495 std::vector<size_t> nEntriesPerRow(ownedPlusSharedRowMap->getLocalNumElements(),0);
1497 std::vector<std::string>::const_iterator blockItr;
1498 for(blockItr=elementBlockIds.begin();blockItr!=elementBlockIds.end();++blockItr) {
1499 const std::vector<LocalOrdinalT> & elements = gidProviders_[0]->getElementBlock(*blockItr);
1501 std::vector<GlobalOrdinalT> row_gids;
1502 std::vector<GlobalOrdinalT> col_gids;
1504 for(std::size_t elmt=0;elmt<elements.size();elmt++) {
1505 rowProvider->getElementGIDs(elements[elmt],row_gids);
1506 colProvider->getElementGIDs(elements[elmt],col_gids);
1507 for(std::size_t row=0;row<row_gids.size();row++) {
1508 LocalOrdinalT lid = ownedPlusSharedRowMap->getLocalElement(row_gids[row]);
1509 nEntriesPerRow[lid] += col_gids.size();
1514 size_t maxNumRowEntries = 0;
1515 for(std::size_t r=0;r<nEntriesPerRow.size();r++)
1516 maxNumRowEntries = std::max(maxNumRowEntries,nEntriesPerRow[r]);
1519 ownedRowMap, ownedPlusSharedRowMap, maxNumRowEntries,
1520 ownedPlusSharedDomainMap,
1528 Teuchos::RCP<Teuchos::ParameterList> feGraphParams = Teuchos::parameterList();
1529 feGraphParams->set(
"Check Col GIDs In At Least One Owned Row",
false);
1530 feGraph->setParameterList(feGraphParams);
1533 feGraph->beginAssembly();
1534 for(blockItr=elementBlockIds.begin();blockItr!=elementBlockIds.end();++blockItr) {
1535 const std::vector<LocalOrdinalT> & elements = gidProviders_[0]->getElementBlock(*blockItr);
1537 std::vector<GlobalOrdinalT> row_gids;
1538 std::vector<GlobalOrdinalT> col_gids;
1540 for(std::size_t elmt=0;elmt<elements.size();elmt++) {
1541 rowProvider->getElementGIDs(elements[elmt],row_gids);
1542 colProvider->getElementGIDs(elements[elmt],col_gids);
1543 for(std::size_t row=0;row<row_gids.size();row++)
1544 feGraph->insertGlobalIndices(row_gids[row],col_gids);
1547 feGraph->endAssembly();
1552template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
1553Teuchos::RCP<typename BlockedTpetraLinearObjFactory<Traits,ScalarT,LocalOrdinalT,GlobalOrdinalT,NodeT>::FECrsGraphType>
1557 TEUCHOS_TEST_FOR_EXCEPTION(!useFEAssembly_,std::logic_error,
1558 "BlockedTpetraLinearObjFactory::getFEGraph: This factory was not constructed with "
1559 "FE assembly enabled.");
1561 typedef std::unordered_map<std::pair<int,int>,Teuchos::RCP<FECrsGraphType>,
panzer::pair_hash> FEGraphMap;
1563 typename FEGraphMap::const_iterator itr = feGraphs_.find(std::make_pair(i,j));
1564 if(itr!=feGraphs_.end())
1567 Teuchos::RCP<FECrsGraphType> graph = buildFEGraph(i,j);
1568 feGraphs_[std::make_pair(i,j)] = graph;
1572template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
1573Teuchos::RCP<typename BlockedTpetraLinearObjFactory<Traits,ScalarT,LocalOrdinalT,GlobalOrdinalT,NodeT>::FECrsMatrixType>
1577 TEUCHOS_TEST_FOR_EXCEPTION(!useFEAssembly_,std::logic_error,
1578 "BlockedTpetraLinearObjFactory::getFEMatrix: This factory was not constructed with "
1579 "FE assembly enabled.");
1586template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
1587Teuchos::RCP<Tpetra::CrsMatrix<ScalarT,LocalOrdinalT,GlobalOrdinalT,NodeT> >
1595 return getFEMatrix(i,j);
1597 Teuchos::RCP<const MapType> map_i = getMap(i);
1598 Teuchos::RCP<const MapType> map_j = getMap(j);
1600 Teuchos::RCP<const CrsGraphType> tGraph = getGraph(i,j);
1601 Teuchos::RCP<CrsMatrixType> mat = Teuchos::rcp(
new CrsMatrixType(tGraph));
1602 mat->fillComplete(map_j,map_i);
1607template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
1608Teuchos::RCP<Tpetra::CrsMatrix<ScalarT,LocalOrdinalT,GlobalOrdinalT,NodeT> >
1616 TEUCHOS_TEST_FOR_EXCEPTION(useFEAssembly_,std::logic_error,
1617 "BlockedTpetraLinearObjFactory::getGhostedTpetraMatrix: not available under FE "
1618 "assembly. The ghosted container shares the owned container's operator, which is "
1619 "connected by beginFill(ghosted,owned); use getFEMatrix(i,j) to allocate a block.");
1621 Teuchos::RCP<const MapType> map_i = getGhostedMap(i);
1622 Teuchos::RCP<const MapType> map_j = getGhostedMap(j);
1624 Teuchos::RCP<const CrsGraphType> tGraph = getGhostedGraph(i,j);
1625 Teuchos::RCP<CrsMatrixType> mat = Teuchos::rcp(
new CrsMatrixType(tGraph));
1626 mat->fillComplete(getMap(j),getMap(i));
1631template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
1632Teuchos::RCP<Tpetra::Vector<ScalarT,LocalOrdinalT,GlobalOrdinalT,NodeT> >
1636 Teuchos::RCP<const MapType> tMap = getColMap(i);
1640template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
1641Teuchos::RCP<Tpetra::Vector<ScalarT,LocalOrdinalT,GlobalOrdinalT,NodeT> >
1645 Teuchos::RCP<const MapType> tMap = getGhostedColMap(i);
1649template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
1650Teuchos::RCP<Tpetra::Vector<ScalarT,LocalOrdinalT,GlobalOrdinalT,NodeT> >
1654 Teuchos::RCP<const MapType> tMap = getMap(i);
1658template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
1659Teuchos::RCP<Tpetra::Vector<ScalarT,LocalOrdinalT,GlobalOrdinalT,NodeT> >
1663 Teuchos::RCP<const MapType> tMap = getGhostedMap(i);
1667template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
1672 return gidProviders_.size();
1675template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
1680 return hasColProvider_ ? colGidProviders_.size() : gidProviders_.size();
1683namespace blocked_tpetra_lof_detail {
1688 template <
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
1689 Teuchos::RCP<Tpetra::CrsMatrix<ScalarT,LocalOrdinalT,GlobalOrdinalT,NodeT> >
1693 using Teuchos::rcp_dynamic_cast;
1695 RCP<Thyra::LinearOpBase<ScalarT> > block = Amat.getNonconstBlock(i,j);
1696 if(block==Teuchos::null)
1697 return Teuchos::null;
1699 RCP<Tpetra::Operator<ScalarT,LocalOrdinalT,GlobalOrdinalT,NodeT> > t_block =
1700 rcp_dynamic_cast<Thyra::TpetraLinearOp<ScalarT,LocalOrdinalT,GlobalOrdinalT,NodeT> >(block,
true)->getTpetraOperator();
1702 return rcp_dynamic_cast<Tpetra::CrsMatrix<ScalarT,LocalOrdinalT,GlobalOrdinalT,NodeT> >(t_block,
true);
1715template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
1726 if(useFEAssembly_) {
1727 const BTLOC & ownedLoc = Teuchos::dyn_cast<const BTLOC>(container);
1728 if(ownedLoc.
get_A()!=Teuchos::null)
1729 Teuchos::dyn_cast<BTLOC>(ghostContainer).set_A(ownedLoc.
get_A());
1732 beginFill(ghostContainer);
1735template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
1740 using Teuchos::rcp_dynamic_cast;
1741 using Thyra::PhysicallyBlockedLinearOpBase;
1743 BTLOC & tloc = Teuchos::dyn_cast<BTLOC>(loc);
1744 if(tloc.
get_A()==Teuchos::null)
1747 if(!useFEAssembly_) {
1752 RCP<PhysicallyBlockedLinearOpBase<ScalarT> > Amat
1753 = rcp_dynamic_cast<PhysicallyBlockedLinearOpBase<ScalarT> >(tloc.
get_A(),
true);
1755 const int blockDim =
static_cast<int>(gidProviders_.size());
1756 for(
int i=0;i<blockDim;i++) {
1757 for(
int j=0;j<blockDim;j++) {
1758 RCP<CrsMatrixType> mat
1759 = blocked_tpetra_lof_detail::getBlockAsCrsMatrix<ScalarT,LocalOrdinalT,GlobalOrdinalT,NodeT>(*Amat,i,j);
1760 if(mat==Teuchos::null)
1763 RCP<FECrsMatrixType> feMat = rcp_dynamic_cast<FECrsMatrixType>(mat);
1764 if(feMat==Teuchos::null) {
1776 const std::pair<int,int> key(i,j);
1778 openItr = feAssemblyOpenOn_.find(key);
1779 if(openItr!=feAssemblyOpenOn_.end() && openItr->second==feMat.get())
1782 feMat->beginAssembly();
1792 feMat->setAllToScalar(0.0);
1794 feAssemblyOpenOn_[key] = feMat.get();
1799template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
1803 endFill(ghostContainer);
1807 if(useFEAssembly_) {
1808 BTLOC & ghostedLoc = Teuchos::dyn_cast<BTLOC>(ghostContainer);
1809 const BTLOC & ownedLoc = Teuchos::dyn_cast<const BTLOC>(container);
1810 if(ghostedLoc.
get_A()!=Teuchos::null && ghostedLoc.
get_A().get()==ownedLoc.
get_A().get())
1811 ghostedLoc.
set_A(Teuchos::null);
1815template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
1820 using Teuchos::rcp_dynamic_cast;
1821 using Thyra::PhysicallyBlockedLinearOpBase;
1823 BTLOC & tloc = Teuchos::dyn_cast<BTLOC>(loc);
1824 if(tloc.
get_A()==Teuchos::null)
1827 if(!useFEAssembly_) {
1832 RCP<PhysicallyBlockedLinearOpBase<ScalarT> > Amat
1833 = rcp_dynamic_cast<PhysicallyBlockedLinearOpBase<ScalarT> >(tloc.
get_A(),
true);
1835 const int blockDim =
static_cast<int>(gidProviders_.size());
1836 for(
int i=0;i<blockDim;i++) {
1837 for(
int j=0;j<blockDim;j++) {
1838 RCP<CrsMatrixType> mat
1839 = blocked_tpetra_lof_detail::getBlockAsCrsMatrix<ScalarT,LocalOrdinalT,GlobalOrdinalT,NodeT>(*Amat,i,j);
1840 if(mat==Teuchos::null)
1843 RCP<FECrsMatrixType> feMat = rcp_dynamic_cast<FECrsMatrixType>(mat);
1844 if(feMat==Teuchos::null) {
1845 mat->fillComplete(getMap(j),getMap(i));
1857 const std::pair<int,int> key(i,j);
1859 openItr = feAssemblyOpenOn_.find(key);
1860 if(openItr!=feAssemblyOpenOn_.end() && openItr->second==feMat.get()) {
1861 feMat->endAssembly();
1862 feAssemblyOpenOn_.erase(key);
PHX::MDField< ScalarT, panzer::Cell, panzer::IP > result
A field that will be used to build up the result of the integral we're performing.
Teuchos::RCP< CrsMatrixType > get_A() const
Teuchos::RCP< VectorType > get_f() const
void set_A(const Teuchos::RCP< CrsMatrixType > &in)
void set_f(const Teuchos::RCP< VectorType > &in)
void set_x(const Teuchos::RCP< VectorType > &in)
Teuchos::RCP< VectorType > get_x() const
Teuchos::RCP< VectorType > get_dxdt() const
void set_dxdt(const Teuchos::RCP< VectorType > &in)
virtual Teuchos::RCP< const MapType > buildColTpetraGhostedMap(int i) const
Teuchos::RCP< FECrsGraphType > getFEGraph(int i, int j) const
Get the (cached) FE graph for block (i,j), built via the Tpetra::FECrsGraph "V2" ctor.
Teuchos::RCP< FECrsMatrixType > getFEMatrix(int i, int j) const
Get the (cached) FECrsMatrix for block (i,j).
Teuchos::RCP< Thyra::VectorBase< ScalarT > > getThyraRangeVector() const
Get a range vector.
virtual void adjustForDirichletConditions(const LinearObjContainer &localBCRows, const LinearObjContainer &globalBCRows, LinearObjContainer &ghostedObjs, bool zeroVectorRows=false, bool adjustX=false) const
virtual void applyDirichletBCs(const LinearObjContainer &counter, LinearObjContainer &result) const
std::vector< Teuchos::RCP< const GlobalIndexer > > gidProviders_
void initializeGhostedContainer(int, LinearObjContainer &loc) const
Teuchos::RCP< Thyra::VectorBase< ScalarT > > getThyraDomainVector() const
Get a domain vector.
Teuchos::RCP< VectorType > getTpetraDomainVector(int i) const
virtual void endFill(LinearObjContainer &loc) const
Close a container after filling. Takes either a ghosted or an owned container.
virtual Teuchos::RCP< FECrsGraphType > buildFEGraph(int i, int j) const
void initializeContainer(int, LinearObjContainer &loc) const
Teuchos::RCP< const Thyra::VectorSpaceBase< ScalarT > > getGhostedThyraDomainSpace() const
Get the domain vector space (x and dxdt)
std::vector< Teuchos::RCP< const GlobalIndexer > > colGidProviders_
Teuchos::RCP< const BlockedDOFManager > blockedDOFManager_
Teuchos::MpiComm< int > getComm() const
virtual Teuchos::RCP< const CrsGraphType > getGhostedGraph(int i, int j) const
get the ghosted graph of the crs matrix
virtual Teuchos::RCP< const MapType > getMap(int i) const
get the map from the matrix
Teuchos::RCP< const GlobalIndexer > getColGlobalIndexer(int i) const
virtual Teuchos::RCP< const ImportType > getGhostedColImport(int i) const
virtual void ghostToGlobalContainer(const LinearObjContainer &ghostContainer, LinearObjContainer &container, int) const
virtual void globalToGhostContainer(const LinearObjContainer &container, LinearObjContainer &ghostContainer, int) const
BlockedTpetraLinearObjFactory(const Teuchos::RCP< const Teuchos::MpiComm< int > > &comm, const Teuchos::RCP< const BlockedDOFManager > &gidProvider, bool useFEAssembly=false)
virtual Teuchos::RCP< const MapType > buildTpetraGhostedMap(int i) const
void globalToGhostThyraVector(const Teuchos::RCP< const Thyra::VectorBase< ScalarT > > &in, const Teuchos::RCP< Thyra::VectorBase< ScalarT > > &out, bool col) const
virtual Teuchos::RCP< const MapType > buildTpetraMap(int i) const
virtual Teuchos::RCP< const CrsGraphType > buildTpetraGraph(int i, int j) const
Teuchos::RCP< VectorType > getGhostedTpetraRangeVector(int i) const
Teuchos::RCP< const Thyra::VectorSpaceBase< ScalarT > > getThyraDomainSpace() const
Get the domain vector space (x and dxdt)
virtual Teuchos::RCP< const MapType > getColMap(int i) const
Teuchos::RCP< Thyra::VectorBase< ScalarT > > getGhostedThyraRangeVector() const
Get a range vector.
Tpetra::CrsGraph< LocalOrdinalT, GlobalOrdinalT, NodeT > CrsGraphType
Tpetra::Export< LocalOrdinalT, GlobalOrdinalT, NodeT > ExportType
virtual Teuchos::RCP< const CrsGraphType > buildTpetraGhostedGraph(int i, int j) const
virtual Teuchos::RCP< const MapType > getGhostedMap(int i) const
get the ghosted map from the matrix
Tpetra::Vector< ScalarT, LocalOrdinalT, GlobalOrdinalT, NodeT > VectorType
Teuchos::RCP< VectorType > getGhostedTpetraDomainVector(int i) const
Teuchos::RCP< const Thyra::VectorSpaceBase< ScalarT > > getGhostedThyraRangeSpace() const
Get the range vector space (f)
void makeRoomForBlocks(std::size_t blockCnt, std::size_t colBlockCnt=0)
Allocate the space in the std::vector objects so we can fill with appropriate Tpetra data.
bool useFEAssembly() const
True if this factory was constructed with FE assembly enabled.
void ghostToGlobalTpetraVector(int i, const VectorType &in, VectorType &out, bool col) const
void globalToGhostTpetraVector(int i, const VectorType &in, VectorType &out, bool col) const
virtual void beginFill(LinearObjContainer &loc) const
Open a container for filling. Takes either a ghosted or an owned container.
Teuchos::RCP< CrsMatrixType > getTpetraMatrix(int i, int j) const
virtual Teuchos::RCP< LinearObjContainer > buildGhostedLinearObjContainer() const
virtual Teuchos::RCP< LinearObjContainer > buildLinearObjContainer() const
int getBlockColCount() const
how many block columns
Tpetra::FECrsGraph< LocalOrdinalT, GlobalOrdinalT, NodeT > FECrsGraphType
void addExcludedPair(int rowBlock, int colBlock)
exclude a block pair from the matrix
void ghostToGlobalThyraMatrix(const Thyra::LinearOpBase< ScalarT > &in, Thyra::LinearOpBase< ScalarT > &out) const
void ghostToGlobalTpetraMatrix(int blockRow, const CrsMatrixType &in, CrsMatrixType &out) const
Tpetra::CrsMatrix< ScalarT, LocalOrdinalT, GlobalOrdinalT, NodeT > CrsMatrixType
Tpetra::Map< LocalOrdinalT, GlobalOrdinalT, NodeT > MapType
Teuchos::RCP< const Thyra::VectorSpaceBase< ScalarT > > getThyraRangeSpace() const
Get the range vector space (f)
static void splitIntoBlocks(const Teuchos::RCP< const GlobalIndexer > &ugi, Teuchos::RCP< const BlockedDOFManager > &blocked, std::vector< Teuchos::RCP< const GlobalIndexer > > &blocks)
virtual Teuchos::RCP< const MapType > buildColTpetraMap(int i) const
Teuchos::RCP< VectorType > getTpetraRangeVector(int i) const
Teuchos::RCP< CrsMatrixType > getGhostedTpetraMatrix(int i, int j) const
virtual Teuchos::RCP< const ImportType > getGhostedImport(int i) const
get importer for converting an overalapped object to a "normal" object
Tpetra::Import< LocalOrdinalT, GlobalOrdinalT, NodeT > ImportType
Teuchos::RCP< const BlockedDOFManager > colBlockedDOFManager_
void addExcludedPairs(const std::vector< std::pair< int, int > > &exPairs)
exclude a vector of pairs from the matrix
virtual Teuchos::RCP< const MapType > getGhostedColMap(int i) const
virtual Teuchos::RCP< const ExportType > getGhostedColExport(int i) const
void ghostToGlobalThyraVector(const Teuchos::RCP< const Thyra::VectorBase< ScalarT > > &in, const Teuchos::RCP< Thyra::VectorBase< ScalarT > > &out, bool col) const
Tpetra::FECrsMatrix< ScalarT, LocalOrdinalT, GlobalOrdinalT, NodeT > FECrsMatrixType
virtual Teuchos::RCP< const ExportType > getGhostedExport(int j) const
get exporter for converting an overalapped object to a "normal" object
Teuchos::RCP< Thyra::LinearOpBase< ScalarT > > getThyraMatrix() const
Get a Thyra operator.
Teuchos::RCP< Thyra::VectorBase< ScalarT > > getGhostedThyraDomainVector() const
Get a domain vector.
virtual Teuchos::RCP< const CrsGraphType > getGraph(int i, int j) const
get the graph of the crs matrix
virtual ~BlockedTpetraLinearObjFactory()
Teuchos::RCP< const panzer::BlockedDOFManager > getGlobalIndexer() const
int getBlockRowCount() const
how many block rows
Teuchos::RCP< Thyra::BlockedLinearOpBase< ScalarT > > getGhostedThyraMatrix() const
Get a Thyra operator.
This class encapsulates the needs of a gather operation to do a halo exchange for blocked vectors.
This class provides a boundary exchange communication mechanism for vectors.
void setRequiresDirichletAdjustment(bool b)
Abstract, linear-algebra-library-agnostic container for the vectors and matrix used in a nonlinear/tr...
void buildGatherScatterEvaluators(const BuilderT &builder)
Teuchos::RCP< Tpetra::CrsMatrix< ScalarT, LocalOrdinalT, GlobalOrdinalT, NodeT > > getBlockAsCrsMatrix(Thyra::PhysicallyBlockedLinearOpBase< ScalarT > &Amat, int i, int j)
Panzer's specialization of the Phalanx traits class.
A hash functor for std::pair, combining the hashes of both elements via hash_combine()....