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_BlockedEpetraOperator.hpp"
00048 #include "Teko_BlockedMappingStrategy.hpp"
00049 #include "Teko_ReorderedMappingStrategy.hpp"
00050
00051 #include "Teuchos_VerboseObject.hpp"
00052
00053 #include "Thyra_LinearOpBase.hpp"
00054 #include "Thyra_EpetraLinearOp.hpp"
00055 #include "Thyra_EpetraThyraWrappers.hpp"
00056 #include "Thyra_DefaultProductMultiVector.hpp"
00057 #include "Thyra_DefaultProductVectorSpace.hpp"
00058 #include "Thyra_DefaultBlockedLinearOp.hpp"
00059 #include "Thyra_get_Epetra_Operator.hpp"
00060
00061 #include "EpetraExt_MultiVectorOut.h"
00062 #include "EpetraExt_RowMatrixOut.h"
00063
00064 #include "Teko_Utilities.hpp"
00065
00066 namespace Teko {
00067 namespace Epetra {
00068
00069 using Teuchos::RCP;
00070 using Teuchos::rcp;
00071 using Teuchos::rcp_dynamic_cast;
00072
00073 BlockedEpetraOperator::BlockedEpetraOperator(const std::vector<std::vector<int> > & vars,
00074 const Teuchos::RCP<const Epetra_Operator> & content,
00075 const std::string & label)
00076 : Teko::Epetra::EpetraOperatorWrapper(), label_(label)
00077 {
00078 SetContent(vars,content);
00079 }
00080
00081 void BlockedEpetraOperator::SetContent(const std::vector<std::vector<int> > & vars,
00082 const Teuchos::RCP<const Epetra_Operator> & content)
00083 {
00084 fullContent_ = content;
00085 blockedMapping_ = rcp(new BlockedMappingStrategy(vars,Teuchos::rcpFromRef(fullContent_->OperatorDomainMap()),
00086 fullContent_->Comm()));
00087 SetMapStrategy(blockedMapping_);
00088
00089
00090 BuildBlockedOperator();
00091 }
00092
00093 void BlockedEpetraOperator::BuildBlockedOperator()
00094 {
00095 TEUCHOS_ASSERT(blockedMapping_!=Teuchos::null);
00096
00097
00098 const RCP<const Epetra_CrsMatrix> crsContent
00099 = rcp_dynamic_cast<const Epetra_CrsMatrix>(fullContent_);
00100
00101
00102 if(blockedOperator_==Teuchos::null) {
00103 blockedOperator_ = blockedMapping_->buildBlockedThyraOp(crsContent,label_);
00104 }
00105 else {
00106 const RCP<Thyra::BlockedLinearOpBase<double> > blkOp
00107 = rcp_dynamic_cast<Thyra::BlockedLinearOpBase<double> >(blockedOperator_,true);
00108 blockedMapping_->rebuildBlockedThyraOp(crsContent,blkOp);
00109 }
00110
00111
00112 SetOperator(blockedOperator_,false);
00113
00114
00115 if(reorderManager_!=Teuchos::null)
00116 Reorder(*reorderManager_);
00117 }
00118
00119 const Teuchos::RCP<const Epetra_Operator> BlockedEpetraOperator::GetBlock(int i,int j) const
00120 {
00121 const RCP<const Thyra::BlockedLinearOpBase<double> > blkOp
00122 = Teuchos::rcp_dynamic_cast<const Thyra::BlockedLinearOpBase<double> >(getThyraOp());
00123
00124 return Thyra::get_Epetra_Operator(*blkOp->getBlock(i,j));
00125 }
00126
00130 void BlockedEpetraOperator::Reorder(const BlockReorderManager & brm)
00131 {
00132 reorderManager_ = rcp(new BlockReorderManager(brm));
00133
00134
00135 RCP<const MappingStrategy> reorderMapping = rcp(new ReorderedMappingStrategy(*reorderManager_,blockedMapping_));
00136 RCP<const Thyra::BlockedLinearOpBase<double> > blockOp
00137 = rcp_dynamic_cast<const Thyra::BlockedLinearOpBase<double> >(blockedOperator_);
00138
00139 RCP<const Thyra::LinearOpBase<double> > A = buildReorderedLinearOp(*reorderManager_,blockOp);
00140
00141
00142 SetMapStrategy(reorderMapping);
00143 SetOperator(A,false);
00144 }
00145
00147 void BlockedEpetraOperator::RemoveReording()
00148 {
00149 SetMapStrategy(blockedMapping_);
00150 SetOperator(blockedOperator_,false);
00151 reorderManager_ = Teuchos::null;
00152 }
00153
00156 void BlockedEpetraOperator::WriteBlocks(const std::string & prefix) const
00157 {
00158 RCP<Thyra::PhysicallyBlockedLinearOpBase<double> > blockOp
00159 = rcp_dynamic_cast<Thyra::PhysicallyBlockedLinearOpBase<double> >(blockedOperator_);
00160
00161
00162 int rows = Teko::blockRowCount(blockOp);
00163
00164 for(int i=0;i<rows;i++) {
00165 for(int j=0;j<rows;j++) {
00166
00167 std::stringstream ss;
00168 ss << prefix << "_" << i << j << ".mm";
00169
00170
00171 RCP<const Epetra_RowMatrix> mat
00172 = Teuchos::rcp_dynamic_cast<const Epetra_RowMatrix>(Thyra::get_Epetra_Operator(*blockOp->getBlock(i,j)));
00173
00174
00175 EpetraExt::RowMatrixToMatrixMarketFile(ss.str().c_str(),*mat);
00176 }
00177 }
00178 }
00179
00180 #ifndef Teko_DEBUG_OFF
00181 bool BlockedEpetraOperator::testAgainstFullOperator(int count,double tol) const
00182 {
00183 Epetra_Vector xf(OperatorRangeMap());
00184 Epetra_Vector xs(OperatorRangeMap());
00185 Epetra_Vector y(OperatorDomainMap());
00186
00187
00188 bool result = true;
00189 double diffNorm=0.0,trueNorm=0.0;
00190 for(int i=0;i<count;i++) {
00191 xf.PutScalar(0.0);
00192 xs.PutScalar(0.0);
00193 y.Random();
00194
00195
00196 Apply(y,xs);
00197 fullContent_->Apply(y,xf);
00198
00199
00200 xs.Update(-1.0,xf,1.0);
00201 xs.Norm2(&diffNorm);
00202 xf.Norm2(&trueNorm);
00203
00204
00205 result &= (diffNorm/trueNorm < tol);
00206 }
00207
00208 return result;
00209 }
00210 #endif
00211
00212 }
00213 }