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,
54 for(std::size_t i=0;i<gidProvider->getFieldDOFManagers().size();i++)
55 gidProviders_.push_back(gidProvider->getFieldDOFManagers()[i]);
61 this->buildGatherScatterEvaluators(*
this);
64template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
67 const std::vector<Teuchos::RCP<const panzer::GlobalIndexer>> & gidProviders,
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,
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;
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;
154 for(std::size_t i=0;i<blockDim;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))
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))
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))
202 if ( !is_null(b_in.
get_f()) && !is_null(b_out.
get_f()) && ((mem & LOC::F)==LOC::F))
205 if ( !is_null(b_in.
get_A()) && !is_null(b_out.
get_A()) && ((mem & LOC::Mat)==LOC::Mat))
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;
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++) {
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) {
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>;
393 auto tvroged = rcp(
new TVROGED);
398 vector<RCP<ReadOnlyVector_GlobalEvaluationData>> gedBlocks;
401 auto tvroged = rcp(
new TVROGED);
403 gedBlocks.push_back(tvroged);
405 auto ged = rcp(
new BVROGED);
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);
448template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
452 BTLOC & bloc = Teuchos::dyn_cast<BTLOC>(loc);
459template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
467 if((mem & LOC::X) == LOC::X)
470 if((mem & LOC::DxDt) == LOC::DxDt)
473 if((mem & LOC::F) == LOC::F)
476 if((mem & LOC::Mat) == LOC::Mat)
480template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
488 if((mem & LOC::X) == LOC::X)
491 if((mem & LOC::DxDt) == LOC::DxDt)
494 if((mem & LOC::F) == LOC::F) {
499 if((mem & LOC::Mat) == LOC::Mat) {
508template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
515template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
519 for(std::size_t i=0;i<exPairs.size();i++)
523template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
524Teuchos::RCP<const GlobalIndexer>
531template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
532Teuchos::RCP<const GlobalIndexer>
539template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
543 maps_.resize(blockCnt);
559template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
560Teuchos::RCP<const Thyra::VectorSpaceBase<ScalarT> >
571 std::vector<Teuchos::RCP<const Thyra::VectorSpaceBase<ScalarT> > > vsArray;
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> >
589 std::vector<Teuchos::RCP<const Thyra::VectorSpaceBase<ScalarT> > > vsArray;
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> >
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> >
630template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
631Teuchos::RCP<Thyra::VectorBase<ScalarT> >
635 Teuchos::RCP<Thyra::VectorBase<ScalarT> > vec =
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) {
646 auto tp_vec = Teuchos::rcp_dynamic_cast<ThyraTpetraVector>(vec,
true)->getTpetraVector();
647 TEUCHOS_ASSERT(tp_vec->getLocalLength()==
getColMap(0)->getLocalNumElements());
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 =
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>();
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++) {
696 Teuchos::RCP<Thyra::LinearOpBase<ScalarT> > block;
698 block = Thyra::tpetraLinearOp<ScalarT,LocalOrdinalT,GlobalOrdinalT,NodeT>(
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> >
725 std::vector<Teuchos::RCP<const Thyra::VectorSpaceBase<ScalarT> > > vsArray;
727 vsArray.push_back(Thyra::createVectorSpace<ScalarT,LocalOrdinalT,GlobalOrdinalT,NodeT>(
getGhostedColMap(i)));
736template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
737Teuchos::RCP<const Thyra::VectorSpaceBase<ScalarT> >
743 std::vector<Teuchos::RCP<const Thyra::VectorSpaceBase<ScalarT> > > vsArray;
745 vsArray.push_back(Thyra::createVectorSpace<ScalarT,LocalOrdinalT,GlobalOrdinalT,NodeT>(
getGhostedMap(i)));
753template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
754Teuchos::RCP<Thyra::VectorBase<ScalarT> >
758 Teuchos::RCP<Thyra::VectorBase<ScalarT> > vec =
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 =
772 Thyra::assign(vec.ptr(),0.0);
777template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
778Teuchos::RCP<Thyra::BlockedLinearOpBase<ScalarT> >
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>();
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++) {
801 Teuchos::RCP<Thyra::LinearOpBase<ScalarT> > block
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;
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();
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;
855 const PhysicallyBlockedLinearOpBase<ScalarT> & prod_in = dyn_cast<const PhysicallyBlockedLinearOpBase<ScalarT> >(in);
856 PhysicallyBlockedLinearOpBase<ScalarT> & prod_out = dyn_cast<PhysicallyBlockedLinearOpBase<ScalarT> >(out);
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++) {
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())
901template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
907 using Teuchos::rcp_dynamic_cast;
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();
932template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
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();
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>
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)
986template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
987Teuchos::RCP<const Tpetra::Map<LocalOrdinalT,GlobalOrdinalT,NodeT> >
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;
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;
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> >
1049template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
1050Teuchos::RCP<const Tpetra::Export<LocalOrdinalT,GlobalOrdinalT,NodeT> >
1060template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
1061Teuchos::RCP<const Tpetra::Map<LocalOrdinalT,GlobalOrdinalT,NodeT> >
1074template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
1075Teuchos::RCP<const Tpetra::Map<LocalOrdinalT,GlobalOrdinalT,NodeT> >
1088template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
1089Teuchos::RCP<const Tpetra::Import<LocalOrdinalT,GlobalOrdinalT,NodeT> >
1102template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
1103Teuchos::RCP<const Tpetra::Export<LocalOrdinalT,GlobalOrdinalT,NodeT> >
1116template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
1117Teuchos::RCP<const Tpetra::Map<LocalOrdinalT,GlobalOrdinalT,NodeT> >
1121 std::vector<GlobalOrdinalT> 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;
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;
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;
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));
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;
1217 std::vector<std::string> elementBlockIds;
1219 Teuchos::RCP<const GlobalIndexer> rowProvider, colProvider;
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 =
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 =
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);
1319 if (result.success()) {
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,
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 =
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 =
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);
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);
1490 std::vector<std::string> 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>
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));
1567 Teuchos::RCP<FECrsGraphType> graph =
buildFEGraph(i,j);
1572template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
1573Teuchos::RCP<typename BlockedTpetraLinearObjFactory<Traits,ScalarT,LocalOrdinalT,GlobalOrdinalT,NodeT>::FECrsMatrixType>
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> >
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> >
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.");
1625 Teuchos::RCP<CrsMatrixType> mat = Teuchos::rcp(
new CrsMatrixType(tGraph));
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> >
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> >
1667template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
1675template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
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>
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());
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)
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
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);
1782 feMat->beginAssembly();
1792 feMat->setAllToScalar(0.0);
1799template <
typename Traits,
typename ScalarT,
typename LocalOrdinalT,
typename GlobalOrdinalT,
typename NodeT>
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)
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
1840 if(mat==Teuchos::null)
1843 RCP<FECrsMatrixType> feMat = rcp_dynamic_cast<FECrsMatrixType>(mat);
1844 if(feMat==Teuchos::null) {
1857 const std::pair<int,int> key(i,j);
1861 feMat->endAssembly();
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)
Teuchos::RCP< const Thyra::VectorSpaceBase< ScalarT > > ghostedDomainSpace_
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
std::vector< Teuchos::RCP< const MapType > > ghostedColMaps_
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< const GlobalIndexer > colBlockProvider_
std::vector< Teuchos::RCP< const ExportType > > colExporters_
Teuchos::RCP< const Teuchos::MpiComm< int > > comm_
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
std::vector< Teuchos::RCP< const MapType > > ghostedMaps_
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
std::vector< Teuchos::RCP< const ExportType > > exporters_
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
Teuchos::RCP< const GlobalIndexer > blockProvider_
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.
std::unordered_map< std::pair< int, int >, Teuchos::RCP< const CrsGraphType >, panzer::pair_hash > graphs_
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
std::unordered_map< std::pair< int, int >, Teuchos::RCP< const CrsGraphType >, panzer::pair_hash > ghostedGraphs_
std::vector< Teuchos::RCP< const ImportType > > colImporters_
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
std::vector< Teuchos::RCP< const MapType > > maps_
virtual Teuchos::RCP< LinearObjContainer > buildLinearObjContainer() const
std::unordered_map< std::pair< int, int >, Teuchos::RCP< FECrsGraphType >, panzer::pair_hash > feGraphs_
int getBlockColCount() const
how many block columns
Tpetra::FECrsGraph< LocalOrdinalT, GlobalOrdinalT, NodeT > FECrsGraphType
std::vector< Teuchos::RCP< const MapType > > colMaps_
void addExcludedPair(int rowBlock, int colBlock)
exclude a block pair from the matrix
std::vector< Teuchos::RCP< const ImportType > > importers_
void ghostToGlobalThyraMatrix(const Thyra::LinearOpBase< ScalarT > &in, Thyra::LinearOpBase< ScalarT > &out) const
void ghostToGlobalTpetraMatrix(int blockRow, const CrsMatrixType &in, CrsMatrixType &out) const
std::unordered_set< std::pair< int, int >, panzer::pair_hash > excludedPairs_
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
Teuchos::RCP< const Thyra::VectorSpaceBase< ScalarT > > domainSpace_
Teuchos::RCP< Thyra::ProductVectorSpaceBase< ScalarT > > ghostedRangeSpace_
virtual Teuchos::RCP< const ImportType > getGhostedImport(int i) const
get importer for converting an overalapped object to a "normal" object
Teuchos::RCP< Thyra::ProductVectorSpaceBase< ScalarT > > rangeSpace_
Tpetra::Import< LocalOrdinalT, GlobalOrdinalT, NodeT > ImportType
Teuchos::RCP< const BlockedDOFManager > colBlockedDOFManager_
BlockedTpetraLinearObjContainer< ScalarT, LocalOrdinalT, GlobalOrdinalT, NodeT > BTLOC
std::unordered_map< std::pair< int, int >, const FECrsMatrixType *, panzer::pair_hash > feAssemblyOpenOn_
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()....