47 #include "Teko_Config.h" 51 #include "Thyra_MultiVectorStdOps.hpp" 52 #include "Thyra_ZeroLinearOpBase.hpp" 53 #include "Thyra_DefaultDiagonalLinearOp.hpp" 54 #include "Thyra_DefaultAddedLinearOp.hpp" 55 #include "Thyra_EpetraExtDiagScaledMatProdTransformer.hpp" 56 #include "Thyra_EpetraExtDiagScalingTransformer.hpp" 57 #include "Thyra_EpetraExtAddTransformer.hpp" 58 #include "Thyra_DefaultScaledAdjointLinearOp.hpp" 59 #include "Thyra_DefaultMultipliedLinearOp.hpp" 60 #include "Thyra_DefaultZeroLinearOp.hpp" 61 #include "Thyra_DefaultProductMultiVector.hpp" 62 #include "Thyra_DefaultProductVectorSpace.hpp" 63 #include "Thyra_MultiVectorStdOps.hpp" 64 #include "Thyra_VectorStdOps.hpp" 65 #include "Thyra_SpmdVectorBase.hpp" 66 #include "Thyra_get_Epetra_Operator.hpp" 67 #include "Thyra_EpetraThyraWrappers.hpp" 68 #include "Thyra_EpetraOperatorWrapper.hpp" 69 #include "Thyra_EpetraLinearOp.hpp" 72 #include "Teuchos_Array.hpp" 75 #include "Epetra_Operator.h" 76 #include "Epetra_CrsGraph.h" 77 #include "Epetra_CrsMatrix.h" 78 #include "Epetra_Vector.h" 79 #include "Epetra_Map.h" 81 #include "EpetraExt_Transpose_RowMatrix.h" 82 #include "EpetraExt_MatrixMatrix.h" 85 #include "AnasaziBasicEigenproblem.hpp" 86 #include "AnasaziThyraAdapter.hpp" 87 #include "AnasaziBlockKrylovSchurSolMgr.hpp" 88 #include "AnasaziBlockKrylovSchur.hpp" 89 #include "AnasaziStatusTestMaxIters.hpp" 92 #ifdef Teko_ENABLE_Isorropia 93 #include "Isorropia_EpetraProber.hpp" 97 #include "Epetra/Teko_EpetraHelpers.hpp" 98 #include "Epetra/Teko_EpetraOperatorWrapper.hpp" 105 using Teuchos::rcp_dynamic_cast;
107 #ifdef Teko_ENABLE_Isorropia 108 using Isorropia::Epetra::Prober;
111 const Teuchos::RCP<Teuchos::FancyOStream> getOutputStream()
113 Teuchos::RCP<Teuchos::FancyOStream> os =
114 Teuchos::VerboseObjectBase::getDefaultOStream();
122 inline double dist(
int dim,
double * coords,
int row,
int col)
125 for(
int i=0;i<dim;i++)
126 value += std::pow(coords[dim*row+i]-coords[dim*col+i],2.0);
129 return std::sqrt(value);
133 inline double dist(
double * x,
double * y,
double * z,
int stride,
int row,
int col)
136 if(x!=0) value += std::pow(x[stride*row]-x[stride*col],2.0);
137 if(y!=0) value += std::pow(y[stride*row]-y[stride*col],2.0);
138 if(z!=0) value += std::pow(z[stride*row]-z[stride*col],2.0);
141 return std::sqrt(value);
162 RCP<Epetra_CrsMatrix> buildGraphLaplacian(
int dim,
double * coords,
const Epetra_CrsMatrix & stencil)
165 RCP<Epetra_CrsMatrix> gl = rcp(
new Epetra_CrsMatrix(Copy,stencil.RowMap(),stencil.ColMap(),
166 stencil.MaxNumEntries()+1),
true);
169 std::vector<double> rowData(stencil.GlobalMaxNumEntries()+1);
170 std::vector<int> rowInd(stencil.GlobalMaxNumEntries()+1);
173 for(
int j=0;j<gl->NumMyRows();j++) {
174 int row = gl->GRID(j);
175 double diagValue = 0.0;
180 stencil.ExtractGlobalRowCopy(row,stencil.MaxNumEntries(),rowSz,&rowData[0],&rowInd[0]);
183 for(
int i=0;i<rowSz;i++) {
187 double value = rowData[i];
188 if(value==0)
continue;
192 double d = dist(dim,coords,row,col);
194 diagValue += rowData[i];
202 rowData[rowSz] = -diagValue;
207 rowData[diagInd] = -diagValue;
208 rowInd[diagInd] = row;
212 TEUCHOS_TEST_FOR_EXCEPT(gl->InsertGlobalValues(row,rowSz,&rowData[0],&rowInd[0]));
242 RCP<Epetra_CrsMatrix> buildGraphLaplacian(
double * x,
double * y,
double * z,
int stride,
const Epetra_CrsMatrix & stencil)
245 RCP<Epetra_CrsMatrix> gl = rcp(
new Epetra_CrsMatrix(Copy,stencil.RowMap(),stencil.ColMap(),
246 stencil.MaxNumEntries()+1),
true);
249 std::vector<double> rowData(stencil.GlobalMaxNumEntries()+1);
250 std::vector<int> rowInd(stencil.GlobalMaxNumEntries()+1);
253 for(
int j=0;j<gl->NumMyRows();j++) {
254 int row = gl->GRID(j);
255 double diagValue = 0.0;
260 stencil.ExtractGlobalRowCopy(row,stencil.MaxNumEntries(),rowSz,&rowData[0],&rowInd[0]);
263 for(
int i=0;i<rowSz;i++) {
267 double value = rowData[i];
268 if(value==0)
continue;
272 double d = dist(x,y,z,stride,row,col);
274 diagValue += rowData[i];
282 rowData[rowSz] = -diagValue;
287 rowData[diagInd] = -diagValue;
288 rowInd[diagInd] = row;
292 TEUCHOS_TEST_FOR_EXCEPT(gl->InsertGlobalValues(row,rowSz,&rowData[0],&rowInd[0]));
315 void applyOp(
const LinearOp & A,
const MultiVector & x,MultiVector & y,
double alpha,
double beta)
318 Thyra::apply(*A,Thyra::NOTRANS,*x,y.ptr(),alpha,beta);
323 void update(
double alpha,
const MultiVector & x,
double beta,MultiVector & y)
325 Teuchos::Array<double>
scale;
326 Teuchos::Array<Teuchos::Ptr<const Thyra::MultiVectorBase<double> > > vec;
329 scale.push_back(alpha);
330 vec.push_back(x.ptr());
333 Thyra::linear_combination<double>(scale,vec,beta,y.ptr());
337 BlockedLinearOp getUpperTriBlocks(
const BlockedLinearOp & blo,
bool callEndBlockFill)
343 RCP<const Thyra::ProductVectorSpaceBase<double> > range = blo->productRange();
344 RCP<const Thyra::ProductVectorSpaceBase<double> > domain = blo->productDomain();
350 upper->beginBlockFill(rows,rows);
352 for(
int i=0;i<rows;i++) {
356 RCP<const Thyra::LinearOpBase<double> > zed
357 = Thyra::zero<double>(range->getBlock(i),domain->getBlock(i));
358 upper->setBlock(i,i,zed);
360 for(
int j=i+1;j<rows;j++) {
362 LinearOp uij = blo->getBlock(i,j);
365 if(uij!=Teuchos::null)
366 upper->setBlock(i,j,uij);
370 upper->endBlockFill();
376 BlockedLinearOp getLowerTriBlocks(
const BlockedLinearOp & blo,
bool callEndBlockFill)
382 RCP<const Thyra::ProductVectorSpaceBase<double> > range = blo->productRange();
383 RCP<const Thyra::ProductVectorSpaceBase<double> > domain = blo->productDomain();
389 lower->beginBlockFill(rows,rows);
391 for(
int i=0;i<rows;i++) {
395 RCP<const Thyra::LinearOpBase<double> > zed
396 = Thyra::zero<double>(range->getBlock(i),domain->getBlock(i));
397 lower->setBlock(i,i,zed);
399 for(
int j=0;j<i;j++) {
401 LinearOp uij = blo->getBlock(i,j);
404 if(uij!=Teuchos::null)
405 lower->setBlock(i,j,uij);
409 lower->endBlockFill();
433 BlockedLinearOp zeroBlockedOp(
const BlockedLinearOp & blo)
439 RCP<const Thyra::ProductVectorSpaceBase<double> > range = blo->productRange();
440 RCP<const Thyra::ProductVectorSpaceBase<double> > domain = blo->productDomain();
446 zeroOp->beginBlockFill(rows,rows);
448 for(
int i=0;i<rows;i++) {
452 RCP<const Thyra::LinearOpBase<double> > zed
453 = Thyra::zero<double>(range->getBlock(i),domain->getBlock(i));
454 zeroOp->setBlock(i,i,zed);
461 bool isZeroOp(
const LinearOp op)
464 if(op==Teuchos::null)
return true;
467 const LinearOp test = rcp_dynamic_cast<
const Thyra::ZeroLinearOpBase<double> >(op);
470 return test!=Teuchos::null;
481 ModifiableLinearOp getAbsRowSumMatrix(
const LinearOp & op)
483 RCP<const Epetra_CrsMatrix> eCrsOp;
487 RCP<const Epetra_Operator> eOp = Thyra::get_Epetra_Operator(*op);
490 eCrsOp = rcp_dynamic_cast<
const Epetra_CrsMatrix>(eOp,
true);
492 catch (std::exception & e) {
493 RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
495 *out <<
"Teko: getAbsRowSumMatrix requires an Epetra_CrsMatrix\n";
496 *out <<
" Could not extract an Epetra_Operator from a \"" << op->description() << std::endl;
498 *out <<
" Could not cast an Epetra_Operator to a Epetra_CrsMatrix\n";
500 *out <<
"*** THROWN EXCEPTION ***\n";
501 *out << e.what() << std::endl;
502 *out <<
"************************\n";
508 const RCP<Epetra_Vector> ptrDiag = rcp(
new Epetra_Vector(eCrsOp->RowMap()));
509 Epetra_Vector & diag = *ptrDiag;
513 for(
int i=0;i<eCrsOp->NumMyRows();i++) {
516 eCrsOp->ExtractMyRowView(i,numEntries,values);
519 for(
int j=0;j<numEntries;j++)
520 diag[i] += std::abs(values[j]);
524 return Teko::Epetra::thyraDiagOp(ptrDiag,eCrsOp->RowMap(),
"absRowSum( " + op->getObjectLabel() +
" )");
535 ModifiableLinearOp getAbsRowSumInvMatrix(
const LinearOp & op)
537 RCP<const Epetra_CrsMatrix> eCrsOp;
541 RCP<const Epetra_Operator> eOp = Thyra::get_Epetra_Operator(*op);
544 eCrsOp = rcp_dynamic_cast<
const Epetra_CrsMatrix>(eOp,
true);
546 catch (std::exception & e) {
547 RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
549 *out <<
"Teko: getAbsRowSumMatrix requires an Epetra_CrsMatrix\n";
550 *out <<
" Could not extract an Epetra_Operator from a \"" << op->description() << std::endl;
552 *out <<
" Could not cast an Epetra_Operator to a Epetra_CrsMatrix\n";
554 *out <<
"*** THROWN EXCEPTION ***\n";
555 *out << e.what() << std::endl;
556 *out <<
"************************\n";
562 const RCP<Epetra_Vector> ptrDiag = rcp(
new Epetra_Vector(eCrsOp->RowMap()));
563 Epetra_Vector & diag = *ptrDiag;
567 for(
int i=0;i<eCrsOp->NumMyRows();i++) {
570 eCrsOp->ExtractMyRowView(i,numEntries,values);
573 for(
int j=0;j<numEntries;j++)
574 diag[i] += std::abs(values[j]);
576 diag.Reciprocal(diag);
579 return Teko::Epetra::thyraDiagOp(ptrDiag,eCrsOp->RowMap(),
"absRowSumInv( " + op->getObjectLabel() +
" )");
589 ModifiableLinearOp getLumpedMatrix(
const LinearOp & op)
591 RCP<Thyra::VectorBase<double> > ones = Thyra::createMember(op->domain());
592 RCP<Thyra::VectorBase<double> > diag = Thyra::createMember(op->range());
595 Thyra::assign(ones.ptr(),1.0);
599 Thyra::apply(*op,Thyra::NOTRANS,*ones,diag.ptr());
601 return rcp(
new Thyra::DefaultDiagonalLinearOp<double>(diag));
612 ModifiableLinearOp getInvLumpedMatrix(
const LinearOp & op)
614 RCP<Thyra::VectorBase<double> > ones = Thyra::createMember(op->domain());
615 RCP<Thyra::VectorBase<double> > diag = Thyra::createMember(op->range());
618 Thyra::assign(ones.ptr(),1.0);
621 Thyra::apply(*op,Thyra::NOTRANS,*ones,diag.ptr());
622 Thyra::reciprocal(*diag,diag.ptr());
624 return rcp(
new Thyra::DefaultDiagonalLinearOp<double>(diag));
638 const ModifiableLinearOp getDiagonalOp(
const LinearOp & op)
640 RCP<const Epetra_CrsMatrix> eCrsOp;
644 RCP<const Epetra_Operator> eOp = Thyra::get_Epetra_Operator(*op);
647 eCrsOp = rcp_dynamic_cast<
const Epetra_CrsMatrix>(eOp,
true);
649 catch (std::exception & e) {
650 RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
652 *out <<
"Teko: getDiagonalOp requires an Epetra_CrsMatrix\n";
653 *out <<
" Could not extract an Epetra_Operator from a \"" << op->description() << std::endl;
655 *out <<
" Could not cast an Epetra_Operator to a Epetra_CrsMatrix\n";
657 *out <<
"*** THROWN EXCEPTION ***\n";
658 *out << e.what() << std::endl;
659 *out <<
"************************\n";
665 const RCP<Epetra_Vector> diag = rcp(
new Epetra_Vector(eCrsOp->RowMap()));
666 TEUCHOS_TEST_FOR_EXCEPT(eCrsOp->ExtractDiagonalCopy(*diag));
669 return Teko::Epetra::thyraDiagOp(diag,eCrsOp->RowMap(),
"diag( " + op->getObjectLabel() +
" )");
672 const MultiVector getDiagonal(
const LinearOp & op)
674 RCP<const Epetra_CrsMatrix> eCrsOp;
678 RCP<const Epetra_Operator> eOp = Thyra::get_Epetra_Operator(*op);
681 eCrsOp = rcp_dynamic_cast<
const Epetra_CrsMatrix>(eOp,
true);
683 catch (std::exception & e) {
684 RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
686 *out <<
"Teko: getDiagonal requires an Epetra_CrsMatrix\n";
687 *out <<
" Could not extract an Epetra_Operator from a \"" << op->description() << std::endl;
689 *out <<
" Could not cast an Epetra_Operator to a Epetra_CrsMatrix\n";
691 *out <<
"*** THROWN EXCEPTION ***\n";
692 *out << e.what() << std::endl;
693 *out <<
"************************\n";
699 const RCP<Epetra_Vector> diag = rcp(
new Epetra_Vector(eCrsOp->RowMap()));
700 TEUCHOS_TEST_FOR_EXCEPT(eCrsOp->ExtractDiagonalCopy(*diag));
702 return Thyra::create_Vector(diag,Thyra::create_VectorSpace(Teuchos::rcpFromRef(eCrsOp->RowMap())));
705 const MultiVector getDiagonal(
const Teko::LinearOp & A,
const DiagonalType & dt)
707 LinearOp diagOp = Teko::getDiagonalOp(A,dt);
709 Teuchos::RCP<const Thyra::MultiVectorBase<double> > v =
710 Teuchos::rcp_dynamic_cast<
const Thyra::DiagonalLinearOpBase<double> >(diagOp)->getDiag();
711 return Teuchos::rcp_const_cast<Thyra::MultiVectorBase<double> >(v);
725 const ModifiableLinearOp getInvDiagonalOp(
const LinearOp & op)
727 RCP<const Epetra_CrsMatrix> eCrsOp;
731 RCP<const Epetra_Operator> eOp = Thyra::get_Epetra_Operator(*op);
734 eCrsOp = rcp_dynamic_cast<
const Epetra_CrsMatrix>(eOp,
true);
736 catch (std::exception & e) {
737 RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
739 *out <<
"Teko: getInvDiagonalOp requires an Epetra_CrsMatrix\n";
740 *out <<
" Could not extract an Epetra_Operator from a \"" << op->description() << std::endl;
742 *out <<
" Could not cast an Epetra_Operator to a Epetra_CrsMatrix\n";
744 *out <<
"*** THROWN EXCEPTION ***\n";
745 *out << e.what() << std::endl;
746 *out <<
"************************\n";
752 const RCP<Epetra_Vector> diag = rcp(
new Epetra_Vector(eCrsOp->RowMap()));
753 TEUCHOS_TEST_FOR_EXCEPT(eCrsOp->ExtractDiagonalCopy(*diag));
754 diag->Reciprocal(*diag);
757 return Teko::Epetra::thyraDiagOp(diag,eCrsOp->RowMap(),
"inv(diag( " + op->getObjectLabel() +
" ))");
772 const LinearOp explicitMultiply(
const LinearOp & opl,
const LinearOp & opm,
const LinearOp & opr)
775 const LinearOp implicitOp = Thyra::multiply(opl,opm,opr);
778 const RCP<Thyra::LinearOpTransformerBase<double> > prodTrans =
779 Thyra::epetraExtDiagScaledMatProdTransformer();
782 const RCP<Thyra::LinearOpBase<double> > explicitOp = prodTrans->createOutputOp();
783 prodTrans->transform(*implicitOp,explicitOp.ptr());
784 explicitOp->setObjectLabel(
"explicit( " + opl->getObjectLabel() +
785 " * " + opm->getObjectLabel() +
786 " * " + opr->getObjectLabel() +
" )");
805 const ModifiableLinearOp explicitMultiply(
const LinearOp & opl,
const LinearOp & opm,
const LinearOp & opr,
806 const ModifiableLinearOp & destOp)
809 const LinearOp implicitOp = Thyra::multiply(opl,opm,opr);
812 const RCP<Thyra::LinearOpTransformerBase<double> > prodTrans =
813 Thyra::epetraExtDiagScaledMatProdTransformer();
816 ModifiableLinearOp explicitOp;
819 if(destOp==Teuchos::null)
820 explicitOp = prodTrans->createOutputOp();
825 prodTrans->transform(*implicitOp,explicitOp.ptr());
828 explicitOp->setObjectLabel(
"explicit( " + opl->getObjectLabel() +
829 " * " + opm->getObjectLabel() +
830 " * " + opr->getObjectLabel() +
" )");
845 const LinearOp explicitMultiply(
const LinearOp & opl,
const LinearOp & opr)
848 const LinearOp implicitOp = Thyra::multiply(opl,opr);
851 RCP<Thyra::LinearOpTransformerBase<double> > prodTrans
852 = Thyra::epetraExtDiagScalingTransformer();
856 if(not prodTrans->isCompatible(*implicitOp))
857 prodTrans = Thyra::epetraExtDiagScaledMatProdTransformer();
860 const RCP<Thyra::LinearOpBase<double> > explicitOp = prodTrans->createOutputOp();
861 prodTrans->transform(*implicitOp,explicitOp.ptr());
862 explicitOp->setObjectLabel(
"explicit( " + opl->getObjectLabel() +
863 " * " + opr->getObjectLabel() +
" )");
881 const ModifiableLinearOp explicitMultiply(
const LinearOp & opl,
const LinearOp & opr,
882 const ModifiableLinearOp & destOp)
885 const LinearOp implicitOp = Thyra::multiply(opl,opr);
888 RCP<Thyra::LinearOpTransformerBase<double> > prodTrans
889 = Thyra::epetraExtDiagScalingTransformer();
893 if(not prodTrans->isCompatible(*implicitOp))
894 prodTrans = Thyra::epetraExtDiagScaledMatProdTransformer();
897 ModifiableLinearOp explicitOp;
900 if(destOp==Teuchos::null)
901 explicitOp = prodTrans->createOutputOp();
906 prodTrans->transform(*implicitOp,explicitOp.ptr());
909 explicitOp->setObjectLabel(
"explicit( " + opl->getObjectLabel() +
910 " * " + opr->getObjectLabel() +
" )");
925 const LinearOp explicitAdd(
const LinearOp & opl,
const LinearOp & opr)
928 const LinearOp implicitOp = Thyra::add(opl,opr);
931 const RCP<Thyra::LinearOpTransformerBase<double> > prodTrans =
932 Thyra::epetraExtAddTransformer();
935 const RCP<Thyra::LinearOpBase<double> > explicitOp = prodTrans->createOutputOp();
936 prodTrans->transform(*implicitOp,explicitOp.ptr());
937 explicitOp->setObjectLabel(
"explicit( " + opl->getObjectLabel() +
938 " + " + opr->getObjectLabel() +
" )");
955 const ModifiableLinearOp explicitAdd(
const LinearOp & opl,
const LinearOp & opr,
956 const ModifiableLinearOp & destOp)
959 const LinearOp implicitOp = Thyra::add(opl,opr);
962 const RCP<Thyra::LinearOpTransformerBase<double> > prodTrans =
963 Thyra::epetraExtAddTransformer();
966 RCP<Thyra::LinearOpBase<double> > explicitOp;
967 if(destOp!=Teuchos::null)
970 explicitOp = prodTrans->createOutputOp();
973 prodTrans->transform(*implicitOp,explicitOp.ptr());
974 explicitOp->setObjectLabel(
"explicit( " + opl->getObjectLabel() +
975 " + " + opr->getObjectLabel() +
" )");
984 const ModifiableLinearOp explicitSum(
const LinearOp & op,
985 const ModifiableLinearOp & destOp)
988 const RCP<const Epetra_CrsMatrix> epetraOp =
989 rcp_dynamic_cast<
const Epetra_CrsMatrix>(get_Epetra_Operator(*op),
true);
991 if(destOp==Teuchos::null) {
992 Teuchos::RCP<Epetra_Operator> epetraDest = Teuchos::rcp(
new Epetra_CrsMatrix(*epetraOp));
994 return Thyra::nonconstEpetraLinearOp(epetraDest);
997 const RCP<Epetra_CrsMatrix> epetraDest =
998 rcp_dynamic_cast<Epetra_CrsMatrix>(get_Epetra_Operator(*destOp),
true);
1000 EpetraExt::MatrixMatrix::Add(*epetraOp,
false,1.0,*epetraDest,1.0);
1005 const LinearOp explicitTranspose(
const LinearOp & op)
1007 RCP<const Epetra_Operator> eOp = Thyra::get_Epetra_Operator(*op);
1008 TEUCHOS_TEST_FOR_EXCEPTION(eOp==Teuchos::null,std::logic_error,
1009 "Teko::explicitTranspose Not an Epetra_Operator");
1010 RCP<const Epetra_RowMatrix> eRowMatrixOp
1011 = Teuchos::rcp_dynamic_cast<
const Epetra_RowMatrix>(eOp);
1012 TEUCHOS_TEST_FOR_EXCEPTION(eRowMatrixOp==Teuchos::null,std::logic_error,
1013 "Teko::explicitTranspose Not an Epetra_RowMatrix");
1016 EpetraExt::RowMatrix_Transpose tranposeOp;
1017 Epetra_RowMatrix & eMat = tranposeOp(const_cast<Epetra_RowMatrix &>(*eRowMatrixOp));
1021 Teuchos::RCP<Epetra_CrsMatrix> crsMat
1022 = Teuchos::rcp(
new Epetra_CrsMatrix(dynamic_cast<Epetra_CrsMatrix &>(eMat)));
1024 return Thyra::epetraLinearOp(crsMat);
1027 const LinearOp buildDiagonal(
const MultiVector & src,
const std::string & lbl)
1029 RCP<Thyra::VectorBase<double> > dst = Thyra::createMember(src->range());
1030 Thyra::copy(*src->col(0),dst.ptr());
1032 return Thyra::diagonal<double>(dst,lbl);
1035 const LinearOp buildInvDiagonal(
const MultiVector & src,
const std::string & lbl)
1037 const RCP<const Thyra::VectorBase<double> > srcV = src->col(0);
1038 RCP<Thyra::VectorBase<double> > dst = Thyra::createMember(srcV->range());
1039 Thyra::reciprocal<double>(*srcV,dst.ptr());
1041 return Thyra::diagonal<double>(dst,lbl);
1045 BlockedMultiVector buildBlockedMultiVector(
const std::vector<MultiVector> & mvv)
1047 Teuchos::Array<MultiVector> mvA;
1048 Teuchos::Array<VectorSpace> vsA;
1051 std::vector<MultiVector>::const_iterator itr;
1052 for(itr=mvv.begin();itr!=mvv.end();++itr) {
1053 mvA.push_back(*itr);
1054 vsA.push_back((*itr)->range());
1058 const RCP<const Thyra::DefaultProductVectorSpace<double> > vs
1059 = Thyra::productVectorSpace<double>(vsA);
1061 return Thyra::defaultProductMultiVector<double>(vs,mvA);
1074 Teuchos::RCP<Thyra::VectorBase<double> > indicatorVector(
1075 const std::vector<int> & indices,
1076 const VectorSpace & vs,
1077 double onValue,
double offValue)
1083 RCP<Thyra::VectorBase<double> > v = Thyra::createMember<double>(vs);
1084 Thyra::put_scalar<double>(offValue,v.ptr());
1087 for(std::size_t i=0;i<indices.size();i++)
1088 Thyra::set_ele<double>(indices[i],onValue,v.ptr());
1117 double computeSpectralRad(
const RCP<
const Thyra::LinearOpBase<double> > & A,
double tol,
1118 bool isHermitian,
int numBlocks,
int restart,
int verbosity)
1120 typedef Thyra::LinearOpBase<double> OP;
1121 typedef Thyra::MultiVectorBase<double> MV;
1123 int startVectors = 1;
1126 const RCP<MV> ivec = Thyra::createMember(A->domain());
1127 Thyra::randomize(-1.0,1.0,ivec.ptr());
1129 RCP<Anasazi::BasicEigenproblem<double,MV,OP> > eigProb
1130 = rcp(
new Anasazi::BasicEigenproblem<double,MV,OP>(A,ivec));
1132 eigProb->setHermitian(isHermitian);
1135 if(not eigProb->setProblem()) {
1137 return Teuchos::ScalarTraits<double>::nan();
1141 std::string which(
"LM");
1145 Teuchos::ParameterList MyPL;
1146 MyPL.set(
"Verbosity", verbosity );
1147 MyPL.set(
"Which", which );
1148 MyPL.set(
"Block Size", startVectors );
1149 MyPL.set(
"Num Blocks", numBlocks );
1150 MyPL.set(
"Maximum Restarts", restart );
1151 MyPL.set(
"Convergence Tolerance", tol );
1159 Anasazi::BlockKrylovSchurSolMgr<double,MV,OP> MyBlockKrylovSchur(eigProb, MyPL );
1162 Anasazi::ReturnType solverreturn = MyBlockKrylovSchur.solve();
1164 if(solverreturn==Anasazi::Unconverged) {
1165 double real = MyBlockKrylovSchur.getRitzValues().begin()->realpart;
1166 double comp = MyBlockKrylovSchur.getRitzValues().begin()->imagpart;
1168 return -std::abs(std::sqrt(real*real+comp*comp));
1174 double real = eigProb->getSolution().Evals.begin()->realpart;
1175 double comp = eigProb->getSolution().Evals.begin()->imagpart;
1177 return std::abs(std::sqrt(real*real+comp*comp));
1207 double computeSmallestMagEig(
const RCP<
const Thyra::LinearOpBase<double> > & A,
double tol,
1208 bool isHermitian,
int numBlocks,
int restart,
int verbosity)
1210 typedef Thyra::LinearOpBase<double> OP;
1211 typedef Thyra::MultiVectorBase<double> MV;
1213 int startVectors = 1;
1216 const RCP<MV> ivec = Thyra::createMember(A->domain());
1217 Thyra::randomize(-1.0,1.0,ivec.ptr());
1219 RCP<Anasazi::BasicEigenproblem<double,MV,OP> > eigProb
1220 = rcp(
new Anasazi::BasicEigenproblem<double,MV,OP>(A,ivec));
1222 eigProb->setHermitian(isHermitian);
1225 if(not eigProb->setProblem()) {
1227 return Teuchos::ScalarTraits<double>::nan();
1231 std::string which(
"SM");
1234 Teuchos::ParameterList MyPL;
1235 MyPL.set(
"Verbosity", verbosity );
1236 MyPL.set(
"Which", which );
1237 MyPL.set(
"Block Size", startVectors );
1238 MyPL.set(
"Num Blocks", numBlocks );
1239 MyPL.set(
"Maximum Restarts", restart );
1240 MyPL.set(
"Convergence Tolerance", tol );
1248 Anasazi::BlockKrylovSchurSolMgr<double,MV,OP> MyBlockKrylovSchur(eigProb, MyPL );
1251 Anasazi::ReturnType solverreturn = MyBlockKrylovSchur.solve();
1253 if(solverreturn==Anasazi::Unconverged) {
1255 return -std::abs(MyBlockKrylovSchur.getRitzValues().begin()->realpart);
1259 return std::abs(eigProb->getSolution().Evals.begin()->realpart);
1271 ModifiableLinearOp getDiagonalOp(
const Teko::LinearOp & A,
const DiagonalType & dt)
1275 return getDiagonalOp(A);
1277 return getLumpedMatrix(A);
1279 return getAbsRowSumMatrix(A);
1282 TEUCHOS_TEST_FOR_EXCEPT(
true);
1285 return Teuchos::null;
1296 ModifiableLinearOp getInvDiagonalOp(
const Teko::LinearOp & A,
const Teko::DiagonalType & dt)
1300 return getInvDiagonalOp(A);
1302 return getInvLumpedMatrix(A);
1304 return getAbsRowSumInvMatrix(A);
1307 TEUCHOS_TEST_FOR_EXCEPT(
true);
1310 return Teuchos::null;
1319 std::string getDiagonalName(
const DiagonalType & dt)
1347 if(name==
"Diagonal")
1351 if(name==
"AbsRowSum")
1359 LinearOp probe(Teuchos::RCP<const Epetra_CrsGraph> &G,
const LinearOp & Op){
1360 #ifdef Teko_ENABLE_Isorropia 1361 Teuchos::ParameterList probeList;
1362 Prober prober(G,probeList,
true);
1363 Teuchos::RCP<Epetra_CrsMatrix> Mat=rcp(
new Epetra_CrsMatrix(Copy,*G));
1365 prober.probe(Mwrap,*Mat);
1366 return Thyra::epetraLinearOp(Mat);
1368 TEUCHOS_TEST_FOR_EXCEPTION(
true,std::runtime_error,
"Probe requires Isorropia");
1372 double norm_1(
const MultiVector & v,std::size_t col)
1374 Teuchos::Array<double> n(v->domain()->dim());
1375 Thyra::norms_1<double>(*v,n);
1380 double norm_2(
const MultiVector & v,std::size_t col)
1382 Teuchos::Array<double> n(v->domain()->dim());
1383 Thyra::norms_2<double>(*v,n);
1388 void putScalar(
const ModifiableLinearOp & op,
double scalar)
1392 RCP<Epetra_Operator> eOp = Thyra::get_Epetra_Operator(*op);
1395 RCP<Epetra_CrsMatrix> eCrsOp = rcp_dynamic_cast<Epetra_CrsMatrix>(eOp,
true);
1397 eCrsOp->PutScalar(scalar);
1399 catch (std::exception & e) {
1400 RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
1402 *out <<
"Teko: putScalar requires an Epetra_CrsMatrix\n";
1403 *out <<
" Could not extract an Epetra_Operator from a \"" << op->description() << std::endl;
1405 *out <<
" Could not cast an Epetra_Operator to a Epetra_CrsMatrix\n";
1407 *out <<
"*** THROWN EXCEPTION ***\n";
1408 *out << e.what() << std::endl;
1409 *out <<
"************************\n";
1415 void clipLower(MultiVector & v,
double lowerBound)
1418 using Teuchos::rcp_dynamic_cast;
1424 for(Thyra::Ordinal i=0;i<v->domain()->dim();i++) {
1425 RCP<Thyra::SpmdVectorBase<double> > spmdVec
1426 = rcp_dynamic_cast<Thyra::SpmdVectorBase<double> >(v->col(i),
true);
1428 Teuchos::ArrayRCP<double> values;
1430 spmdVec->getNonconstLocalData(Teuchos::ptrFromRef(values));
1431 for(Teuchos::ArrayRCP<double>::size_type j=0;j<values.size();j++) {
1432 if(values[j]<lowerBound)
1433 values[j] = lowerBound;
1438 void clipUpper(MultiVector & v,
double upperBound)
1441 using Teuchos::rcp_dynamic_cast;
1446 for(Thyra::Ordinal i=0;i<v->domain()->dim();i++) {
1447 RCP<Thyra::SpmdVectorBase<double> > spmdVec
1448 = rcp_dynamic_cast<Thyra::SpmdVectorBase<double> >(v->col(i),
true);
1450 Teuchos::ArrayRCP<double> values;
1452 spmdVec->getNonconstLocalData(Teuchos::ptrFromRef(values));
1453 for(Teuchos::ArrayRCP<double>::size_type j=0;j<values.size();j++) {
1454 if(values[j]>upperBound)
1455 values[j] = upperBound;
1460 void replaceValue(MultiVector & v,
double currentValue,
double newValue)
1463 using Teuchos::rcp_dynamic_cast;
1468 for(Thyra::Ordinal i=0;i<v->domain()->dim();i++) {
1469 RCP<Thyra::SpmdVectorBase<double> > spmdVec
1470 = rcp_dynamic_cast<Thyra::SpmdVectorBase<double> >(v->col(i),
true);
1472 Teuchos::ArrayRCP<double> values;
1474 spmdVec->getNonconstLocalData(Teuchos::ptrFromRef(values));
1475 for(Teuchos::ArrayRCP<double>::size_type j=0;j<values.size();j++) {
1476 if(values[j]==currentValue)
1477 values[j] = newValue;
1482 void columnAverages(
const MultiVector & v,std::vector<double> & averages)
1484 averages.resize(v->domain()->dim());
1487 Thyra::sums<double>(*v,averages);
1490 Thyra::Ordinal rows = v->range()->dim();
1491 for(std::size_t i=0;i<averages.size();i++)
1492 averages[i] = averages[i]/rows;
1495 double average(
const MultiVector & v)
1497 Thyra::Ordinal rows = v->range()->dim();
1498 Thyra::Ordinal cols = v->domain()->dim();
1500 std::vector<double> averages;
1501 columnAverages(v,averages);
1504 for(std::size_t i=0;i<averages.size();i++)
1505 sum += averages[i] * rows;
1507 return sum/(rows*cols);
Specifies that a block diagonal approximation is to be used.
Specifies that just the diagonal is used.
int blockRowCount(const BlockedLinearOp &blo)
Get the row count in a block linear operator.
Specifies that row sum is used to form a diagonal.
void scale(const double alpha, MultiVector &x)
Scale a multivector by a constant.
Implements the Epetra_Operator interface with a Thyra LinearOperator. This enables the use of absrtac...
For user convenience, if Teko recieves this value, exceptions will be thrown.
DiagonalType
Type describing the type of diagonal to construct.
int blockColCount(const BlockedLinearOp &blo)
Get the column count in a block linear operator.
BlockedLinearOp createBlockedOp()
Build a new blocked linear operator.
Specifies that the diagonal entry is .