00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 #include "Teko_EpetraHelpers.hpp"
00048
00049
00050 #include "Thyra_EpetraLinearOp.hpp"
00051 #include "Thyra_BlockedLinearOpBase.hpp"
00052 #include "Thyra_DefaultMultipliedLinearOp.hpp"
00053 #include "Thyra_DefaultDiagonalLinearOp.hpp"
00054 #include "Thyra_DefaultZeroLinearOp.hpp"
00055 #include "Thyra_DefaultBlockedLinearOp.hpp"
00056 #include "Thyra_EpetraThyraWrappers.hpp"
00057 #include "Thyra_SpmdVectorBase.hpp"
00058 #include "Thyra_SpmdVectorSpaceBase.hpp"
00059 #include "Thyra_ScalarProdVectorSpaceBase.hpp"
00060
00061
00062 #include "Epetra_Vector.h"
00063
00064
00065 #include "EpetraExt_ProductOperator.h"
00066 #include "EpetraExt_MatrixMatrix.h"
00067
00068
00069 #include "Teko_EpetraOperatorWrapper.hpp"
00070 #include "Teko_Utilities.hpp"
00071
00072 using Teuchos::RCP;
00073 using Teuchos::rcp;
00074 using Teuchos::rcpFromRef;
00075 using Teuchos::rcp_dynamic_cast;
00076 using Teuchos::null;
00077
00078 namespace Teko {
00079 namespace Epetra {
00080
00091 const Teuchos::RCP<const Thyra::LinearOpBase<double> > thyraDiagOp(const RCP<const Epetra_Vector> & ev,const Epetra_Map & map,
00092 const std::string & lbl)
00093 {
00094 const RCP<const Thyra::VectorBase<double> > thyraVec
00095 = Thyra::create_Vector(ev,Thyra::create_VectorSpace(rcpFromRef(map)));
00096 Teuchos::RCP<Thyra::LinearOpBase<double> > op
00097 = Teuchos::rcp(new Thyra::DefaultDiagonalLinearOp<double>(thyraVec));
00098 op->setObjectLabel(lbl);
00099 return op;
00100 }
00101
00112 const Teuchos::RCP<Thyra::LinearOpBase<double> > thyraDiagOp(const RCP<Epetra_Vector> & ev,const Epetra_Map & map,
00113 const std::string & lbl)
00114 {
00115 const RCP<Thyra::VectorBase<double> > thyraVec
00116 = Thyra::create_Vector(ev,Thyra::create_VectorSpace(rcpFromRef(map)));
00117 Teuchos::RCP<Thyra::LinearOpBase<double> > op
00118 = Teuchos::rcp(new Thyra::DefaultDiagonalLinearOp<double>(thyraVec));
00119 op->setObjectLabel(lbl);
00120 return op;
00121 }
00122
00132 void fillDefaultSpmdMultiVector(Teuchos::RCP<Thyra::DefaultSpmdMultiVector<double> > & spmdMV,
00133 Teuchos::RCP<Epetra_MultiVector> & epetraMV)
00134 {
00135
00136 const RCP<const Thyra::SpmdVectorSpaceBase<double> > range = spmdMV->spmdSpace();
00137 const RCP<const Thyra::ScalarProdVectorSpaceBase<double> > domain
00138 = rcp_dynamic_cast<const Thyra::ScalarProdVectorSpaceBase<double> >(spmdMV->domain());
00139
00140 TEUCHOS_ASSERT(domain->dim()==epetraMV->NumVectors());
00141
00142
00143 double *localValues; int leadingDim;
00144 if(epetraMV->ConstantStride() )
00145 epetraMV->ExtractView( &localValues, &leadingDim );
00146 else
00147 TEUCHOS_TEST_FOR_EXCEPT(true);
00148
00149
00150 spmdMV->initialize(range, domain,
00151 Teuchos::arcp(localValues,0,leadingDim*epetraMV->NumVectors(),false),
00152 leadingDim);
00153
00154
00155 Teuchos::set_extra_data<RCP<Epetra_MultiVector> >(epetraMV,"Epetra_MultiVector",Teuchos::outArg(spmdMV));
00156 }
00157
00167 void identityRowIndices(const Epetra_Map & rowMap, const Epetra_CrsMatrix & mat,std::vector<int> & outIndices)
00168 {
00169 int maxSz = mat.GlobalMaxNumEntries();
00170 std::vector<double> values(maxSz);
00171 std::vector<int> indices(maxSz);
00172
00173
00174 for(int i=0;i<rowMap.NumMyElements();i++) {
00175 bool rowIsIdentity = true;
00176 int sz = 0;
00177 int rowGID = rowMap.GID(i);
00178 mat.ExtractGlobalRowCopy(rowGID,maxSz,sz,&values[0],&indices[0]);
00179
00180
00181 for(int j=0;j<sz;j++) {
00182 int colGID = indices[j];
00183
00184
00185 if(colGID==rowGID) rowIsIdentity &= values[j]==1.0;
00186 else rowIsIdentity &= values[j]==0.0;
00187
00188
00189 if(not rowIsIdentity)
00190 break;
00191 }
00192
00193
00194 if(rowIsIdentity)
00195 outIndices.push_back(rowGID);
00196 }
00197 }
00198
00209 void zeroMultiVectorRowIndices(Epetra_MultiVector & mv,const std::vector<int> & zeroIndices)
00210 {
00211 int colCnt = mv.NumVectors();
00212 std::vector<int>::const_iterator itr;
00213
00214
00215 for(itr=zeroIndices.begin();itr!=zeroIndices.end();++itr) {
00216
00217
00218 for(int j=0;j<colCnt;j++)
00219 TEUCHOS_TEST_FOR_EXCEPT(mv.ReplaceGlobalValue(*itr,j,0.0));
00220 }
00221 }
00222
00232 ZeroedOperator::ZeroedOperator(const std::vector<int> & zeroIndices,
00233 const Teuchos::RCP<const Epetra_Operator> & op)
00234 : zeroIndices_(zeroIndices), epetraOp_(op)
00235 { }
00236
00238 int ZeroedOperator::Apply(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const
00239 {
00240
00241
00242
00243
00244
00245
00246 int result = epetraOp_->Apply(X,Y);
00247
00248
00249 zeroMultiVectorRowIndices(Y,zeroIndices_);
00250
00251 return result;
00252 }
00253
00254 }
00255 }