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 "Epetra/Teko_BlockedMappingStrategy.hpp"
00048 #include "Epetra/Teko_EpetraHelpers.hpp"
00049
00050 #include "Thyra_EpetraThyraWrappers.hpp"
00051 #include "Thyra_EpetraLinearOp.hpp"
00052 #include "Thyra_DefaultProductMultiVector.hpp"
00053 #include "Thyra_DefaultProductVectorSpace.hpp"
00054 #include "Thyra_DefaultSpmdMultiVector.hpp"
00055 #include "Thyra_DefaultBlockedLinearOp.hpp"
00056 #include "Thyra_get_Epetra_Operator.hpp"
00057
00058 using Teuchos::RCP;
00059 using Teuchos::rcp;
00060 using Teuchos::rcp_dynamic_cast;
00061
00062 namespace Teko {
00063 namespace Epetra {
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 BlockedMappingStrategy::BlockedMappingStrategy(const std::vector<std::vector<int> > & vars,
00076 const Teuchos::RCP<const Epetra_Map> & map, const Epetra_Comm & comm)
00077 {
00078 rangeMap_ = map;
00079 domainMap_ = map;
00080 buildBlockTransferData(vars, rangeMap_,comm);
00081 }
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 void BlockedMappingStrategy::copyEpetraIntoThyra(const Epetra_MultiVector& X,
00092 const Teuchos::Ptr<Thyra::MultiVectorBase<double> > & thyra_X) const
00093 {
00094 int count = X.NumVectors();
00095
00096 std::vector<RCP<Epetra_MultiVector> > subX;
00097
00098
00099 Blocking::buildSubVectors(blockMaps_,subX,count);
00100
00101
00102 Blocking::one2many(subX,X,blockImport_);
00103
00104
00105 Teuchos::Array<RCP<Thyra::MultiVectorBase<double> > > thyra_subX;
00106 Teuchos::Ptr<Thyra::ProductMultiVectorBase<double> > prod_X
00107 = Teuchos::ptr_dynamic_cast<Thyra::ProductMultiVectorBase<double> >(thyra_X);
00108 for(unsigned int i=0;i<blockMaps_.size();i++) {
00109 RCP<Thyra::DefaultSpmdMultiVector<double> > vec
00110 = rcp_dynamic_cast<Thyra::DefaultSpmdMultiVector<double> >(prod_X->getNonconstMultiVectorBlock(i));
00111 fillDefaultSpmdMultiVector(vec,subX[i]);
00112 }
00113 }
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123 void BlockedMappingStrategy::copyThyraIntoEpetra(const RCP<const Thyra::MultiVectorBase<double> > & thyra_Y,
00124 Epetra_MultiVector& Y) const
00125 {
00126 std::vector<RCP<const Epetra_MultiVector> > subY;
00127 RCP<const Thyra::DefaultProductMultiVector<double> > prod_Y
00128 = rcp_dynamic_cast<const Thyra::DefaultProductMultiVector<double> >(thyra_Y);
00129
00130
00131 for(unsigned int i=0;i<blockMaps_.size();i++)
00132 subY.push_back(Thyra::get_Epetra_MultiVector(*blockMaps_[i].second,prod_Y->getMultiVectorBlock(i)));
00133
00134
00135
00136
00137
00138 Blocking::many2one(Y,subY,blockExport_);
00139 }
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153 void BlockedMappingStrategy::buildBlockTransferData(const std::vector<std::vector<int> > & vars,
00154 const Teuchos::RCP<const Epetra_Map> & baseMap, const Epetra_Comm & comm)
00155 {
00156
00157 for(std::size_t i=0;i<vars.size();i++) {
00158
00159 Blocking::MapPair mapPair = Blocking::buildSubMap(vars[i],comm);
00160 Blocking::ImExPair iePair = Blocking::buildExportImport(*baseMap, mapPair);
00161
00162 blockMaps_.push_back(mapPair);
00163 blockImport_.push_back(iePair.first);
00164 blockExport_.push_back(iePair.second);
00165 }
00166 }
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 const Teuchos::RCP<Thyra::BlockedLinearOpBase<double> >
00179 BlockedMappingStrategy::buildBlockedThyraOp(const RCP<const Epetra_CrsMatrix> & crsContent,const std::string & label) const
00180 {
00181 int dim = blockMaps_.size();
00182
00183 RCP<Thyra::DefaultBlockedLinearOp<double> > A = Thyra::defaultBlockedLinearOp<double>();
00184
00185 A->beginBlockFill(dim,dim);
00186 for(int i=0;i<dim;i++) {
00187 for(int j=0;j<dim;j++) {
00188
00189 std::stringstream ss;
00190 ss << label << "_" << i << "," << j;
00191
00192
00193 RCP<Epetra_CrsMatrix> blk = Blocking::buildSubBlock(i,j,*crsContent,blockMaps_);
00194 A->setNonconstBlock(i,j,Thyra::nonconstEpetraLinearOp(blk,ss.str()));
00195 }
00196 }
00197 A->endBlockFill();
00198
00199 return A;
00200 }
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212 void BlockedMappingStrategy::rebuildBlockedThyraOp(const RCP<const Epetra_CrsMatrix> & crsContent,
00213 const RCP<Thyra::BlockedLinearOpBase<double> > & A) const
00214 {
00215 int dim = blockMaps_.size();
00216
00217 for(int i=0;i<dim;i++) {
00218 for(int j=0;j<dim;j++) {
00219
00220 RCP<Thyra::LinearOpBase<double> > Aij = A->getNonconstBlock(i,j);
00221 RCP<Epetra_CrsMatrix> eAij = rcp_dynamic_cast<Epetra_CrsMatrix>(Thyra::get_Epetra_Operator(*Aij),true);
00222
00223
00224 Blocking::rebuildSubBlock(i,j,*crsContent,blockMaps_,*eAij);
00225 }
00226 }
00227 }
00228
00229 }
00230 }