47 #include "Teko_TpetraThyraConverter.hpp"
48 #include "Tpetra_Core.hpp"
51 #include "Teuchos_Array.hpp"
52 #include "Teuchos_ArrayRCP.hpp"
55 #include "Thyra_DefaultProductVectorSpace.hpp"
56 #include "Thyra_DefaultProductMultiVector.hpp"
57 #include "Thyra_SpmdMultiVectorBase.hpp"
58 #include "Thyra_SpmdVectorSpaceBase.hpp"
59 #include "Thyra_MultiVectorStdOps.hpp"
67 using Teuchos::rcpFromRef;
68 using Teuchos::rcp_dynamic_cast;
69 using Teuchos::ptr_dynamic_cast;
73 namespace TpetraHelpers {
78 void blockTpetraToThyra(
int numVectors,Teuchos::ArrayRCP<const ST> tpetraData,
int leadingDim,
const Teuchos::Ptr<Thyra::MultiVectorBase<ST> > & mv,
int & localDim)
83 const Ptr<Thyra::ProductMultiVectorBase<ST> > prodMV
84 = ptr_dynamic_cast<Thyra::ProductMultiVectorBase<ST> > (mv);
85 if(prodMV==Teuchos::null) {
87 const Ptr<Thyra::SpmdMultiVectorBase<ST> > spmdX = ptr_dynamic_cast<Thyra::SpmdMultiVectorBase<ST> >(mv,
true);
88 const RCP<const Thyra::SpmdVectorSpaceBase<ST> > spmdVS = spmdX->spmdSpace();
90 int localSubDim = spmdVS->localSubDim();
92 Thyra::Ordinal thyraLeadingDim=0;
94 Teuchos::ArrayRCP<ST> thyraData_arcp;
95 Teuchos::ArrayView<ST> thyraData;
96 spmdX->getNonconstLocalData(Teuchos::outArg(thyraData_arcp),Teuchos::outArg(thyraLeadingDim));
97 thyraData = thyraData_arcp();
99 for(
int i=0;i<localSubDim;i++) {
101 for(
int v=0;v<numVectors;v++)
102 thyraData[i+thyraLeadingDim*v] = tpetraData[i+leadingDim*v];
106 localDim = localSubDim;
112 Teuchos::ArrayRCP<const ST> localData = tpetraData;
115 for(
int blkIndex=0;blkIndex<prodMV->productSpace()->numBlocks();blkIndex++) {
117 const RCP<Thyra::MultiVectorBase<ST> > blockVec = prodMV->getNonconstMultiVectorBlock(blkIndex);
120 blockTpetraToThyra(numVectors, localData,leadingDim,blockVec.ptr(),subDim);
133 void blockTpetraToThyra(
const Tpetra::MultiVector<ST,LO,GO,NT> & tpetraX,
const Teuchos::Ptr<Thyra::MultiVectorBase<ST> > & thyraX)
135 TEUCHOS_ASSERT((Tpetra::global_size_t) thyraX->range()->dim()==tpetraX.getGlobalLength());
138 LO leadingDim=0,localDim=0;
139 leadingDim = tpetraX.getStride();
140 Teuchos::ArrayRCP<const ST> tpetraData = tpetraX.get1dView();
142 int numVectors = tpetraX.getNumVectors();
144 blockTpetraToThyra(numVectors,tpetraData,leadingDim,thyraX.ptr(),localDim);
146 TEUCHOS_ASSERT((
size_t) localDim==tpetraX.getLocalLength());
149 void blockThyraToTpetra(LO numVectors,Teuchos::ArrayRCP<ST> tpetraData,LO leadingDim,
const Teuchos::RCP<
const Thyra::MultiVectorBase<ST> > & tX,LO & localDim)
154 const RCP<const Thyra::ProductMultiVectorBase<ST> > prodX
155 = rcp_dynamic_cast<
const Thyra::ProductMultiVectorBase<ST> > (tX);
156 if(prodX==Teuchos::null) {
160 RCP<const Thyra::SpmdMultiVectorBase<ST> > spmdX = rcp_dynamic_cast<
const Thyra::SpmdMultiVectorBase<ST> >(tX,
true);
161 RCP<const Thyra::SpmdVectorSpaceBase<ST> > spmdVS = spmdX->spmdSpace();
163 Thyra::Ordinal thyraLeadingDim=0;
164 Teuchos::ArrayView<const ST> thyraData;
165 Teuchos::ArrayRCP<const ST> thyraData_arcp;
166 spmdX->getLocalData(Teuchos::outArg(thyraData_arcp),Teuchos::outArg(thyraLeadingDim));
167 thyraData = thyraData_arcp();
169 LO localSubDim = spmdVS->localSubDim();
170 for(LO i=0;i<localSubDim;i++) {
172 for(LO v=0;v<numVectors;v++){
173 tpetraData[i+leadingDim*v] = thyraData[i+thyraLeadingDim*v];
178 localDim = localSubDim;
183 const RCP<const Thyra::ProductVectorSpaceBase<ST> > prodVS = prodX->productSpace();
186 Teuchos::ArrayRCP<ST> localData = tpetraData;
189 for(
int blkIndex=0;blkIndex<prodVS->numBlocks();blkIndex++) {
193 blockThyraToTpetra(numVectors, localData,leadingDim,prodX->getMultiVectorBlock(blkIndex),subDim);
209 void blockThyraToTpetra(
const Teuchos::RCP<
const Thyra::MultiVectorBase<ST> > & thyraX,Tpetra::MultiVector<ST,LO,GO,NT> & tpetraX)
212 LO numVectors = thyraX->domain()->dim();
215 TEUCHOS_ASSERT((
size_t) numVectors==tpetraX.getNumVectors());
216 TEUCHOS_ASSERT((Tpetra::global_size_t) thyraX->range()->dim()==tpetraX.getGlobalLength());
219 LO leadingDim=0,localDim=0;
220 leadingDim = tpetraX.getStride();
221 Teuchos::ArrayRCP<ST> tpetraData = tpetraX.get1dViewNonConst();
224 blockThyraToTpetra(numVectors,tpetraData,leadingDim,thyraX,localDim);
227 TEUCHOS_ASSERT((
size_t) localDim==tpetraX.getLocalLength());
230 void thyraVSToTpetraMap(std::vector<GO> & myIndicies,
int blockOffset,
const Thyra::VectorSpaceBase<ST> & vs,
int & localDim)
235 const RCP<const Thyra::ProductVectorSpaceBase<ST> > prodVS
236 = rcp_dynamic_cast<
const Thyra::ProductVectorSpaceBase<ST> >(rcpFromRef(vs));
239 if(prodVS==Teuchos::null) {
243 const RCP<const Thyra::SpmdVectorSpaceBase<ST> > spmdVS
244 = rcp_dynamic_cast<
const Thyra::SpmdVectorSpaceBase<ST> >(rcpFromRef(vs));
245 TEUCHOS_TEST_FOR_EXCEPTION(spmdVS==Teuchos::null,std::runtime_error,
246 "thyraVSToTpetraMap requires all subblocks to be SPMD");
249 int localOffset = spmdVS->localOffset();
250 int localSubDim = spmdVS->localSubDim();
253 for(
int i=0;i<localSubDim;i++)
254 myIndicies.push_back(blockOffset+localOffset+i);
256 localDim += localSubDim;
262 for(
int blkIndex=0;blkIndex<prodVS->numBlocks();blkIndex++) {
266 thyraVSToTpetraMap(myIndicies, blockOffset,*prodVS->getBlock(blkIndex),subDim);
268 blockOffset += prodVS->getBlock(blkIndex)->dim();
276 const RCP<Tpetra::Map<LO,GO,NT> > thyraVSToTpetraMap(
const Thyra::VectorSpaceBase<ST> & vs,
const RCP<
const Teuchos::Comm<Thyra::Ordinal> > & )
279 std::vector<GO> myGIDs;
282 thyraVSToTpetraMap(myGIDs,0,vs,localDim);
284 TEUCHOS_ASSERT(myGIDs.size() == (size_t) localDim);
290 return rcp(
new Tpetra::Map<LO,GO,NT>(vs.dim(), Teuchos::ArrayView<const GO>(myGIDs), 0, Tpetra::getDefaultComm()));