10 #include "Teko_TpetraThyraConverter.hpp"
11 #include "Tpetra_Core.hpp"
14 #include "Teuchos_Array.hpp"
15 #include "Teuchos_ArrayRCP.hpp"
18 #include "Thyra_DefaultProductVectorSpace.hpp"
19 #include "Thyra_DefaultProductMultiVector.hpp"
20 #include "Thyra_SpmdMultiVectorBase.hpp"
21 #include "Thyra_SpmdVectorSpaceBase.hpp"
22 #include "Thyra_MultiVectorStdOps.hpp"
29 using Teuchos::ptr_dynamic_cast;
32 using Teuchos::rcp_dynamic_cast;
33 using Teuchos::rcpFromRef;
36 namespace TpetraHelpers {
42 void blockTpetraToThyra(
int numVectors, Teuchos::ArrayRCP<const ST> tpetraData,
int leadingDim,
43 const Teuchos::Ptr<Thyra::MultiVectorBase<ST> >& mv,
int& localDim) {
47 const Ptr<Thyra::ProductMultiVectorBase<ST> > prodMV =
48 ptr_dynamic_cast<Thyra::ProductMultiVectorBase<ST> >(mv);
49 if (prodMV == Teuchos::null) {
51 const Ptr<Thyra::SpmdMultiVectorBase<ST> > spmdX =
52 ptr_dynamic_cast<Thyra::SpmdMultiVectorBase<ST> >(mv,
true);
53 const RCP<const Thyra::SpmdVectorSpaceBase<ST> > spmdVS = spmdX->spmdSpace();
55 int localSubDim = spmdVS->localSubDim();
57 Thyra::Ordinal thyraLeadingDim = 0;
59 Teuchos::ArrayRCP<ST> thyraData_arcp;
60 Teuchos::ArrayView<ST> thyraData;
61 spmdX->getNonconstLocalData(Teuchos::outArg(thyraData_arcp), Teuchos::outArg(thyraLeadingDim));
62 thyraData = thyraData_arcp();
64 for (
int i = 0; i < localSubDim; i++) {
66 for (
int v = 0; v < numVectors; v++)
67 thyraData[i + thyraLeadingDim * v] = tpetraData[i + leadingDim * v];
71 localDim = localSubDim;
77 Teuchos::ArrayRCP<const ST> localData = tpetraData;
80 for (
int blkIndex = 0; blkIndex < prodMV->productSpace()->numBlocks(); blkIndex++) {
82 const RCP<Thyra::MultiVectorBase<ST> > blockVec = prodMV->getNonconstMultiVectorBlock(blkIndex);
85 blockTpetraToThyra(numVectors, localData, leadingDim, blockVec.ptr(), subDim);
99 void blockTpetraToThyra(
const Tpetra::MultiVector<ST, LO, GO, NT>& tpetraX,
100 const Teuchos::Ptr<Thyra::MultiVectorBase<ST> >& thyraX) {
101 TEUCHOS_ASSERT((Tpetra::global_size_t)thyraX->range()->dim() == tpetraX.getGlobalLength());
104 LO leadingDim = 0, localDim = 0;
105 leadingDim = tpetraX.getStride();
106 Teuchos::ArrayRCP<const ST> tpetraData = tpetraX.get1dView();
108 int numVectors = tpetraX.getNumVectors();
110 blockTpetraToThyra(numVectors, tpetraData, leadingDim, thyraX.ptr(), localDim);
112 TEUCHOS_ASSERT((
size_t)localDim == tpetraX.getLocalLength());
115 void blockThyraToTpetra(LO numVectors, Teuchos::ArrayRCP<ST> tpetraData, LO leadingDim,
116 const Teuchos::RCP<
const Thyra::MultiVectorBase<ST> >& tX, LO& localDim) {
120 const RCP<const Thyra::ProductMultiVectorBase<ST> > prodX =
121 rcp_dynamic_cast<
const Thyra::ProductMultiVectorBase<ST> >(tX);
122 if (prodX == Teuchos::null) {
126 RCP<const Thyra::SpmdMultiVectorBase<ST> > spmdX =
127 rcp_dynamic_cast<
const Thyra::SpmdMultiVectorBase<ST> >(tX,
true);
128 RCP<const Thyra::SpmdVectorSpaceBase<ST> > spmdVS = spmdX->spmdSpace();
130 Thyra::Ordinal thyraLeadingDim = 0;
131 Teuchos::ArrayView<const ST> thyraData;
132 Teuchos::ArrayRCP<const ST> thyraData_arcp;
133 spmdX->getLocalData(Teuchos::outArg(thyraData_arcp), Teuchos::outArg(thyraLeadingDim));
134 thyraData = thyraData_arcp();
136 LO localSubDim = spmdVS->localSubDim();
137 for (LO i = 0; i < localSubDim; i++) {
139 for (LO v = 0; v < numVectors; v++) {
140 tpetraData[i + leadingDim * v] = thyraData[i + thyraLeadingDim * v];
145 localDim = localSubDim;
150 const RCP<const Thyra::ProductVectorSpaceBase<ST> > prodVS = prodX->productSpace();
153 Teuchos::ArrayRCP<ST> localData = tpetraData;
156 for (
int blkIndex = 0; blkIndex < prodVS->numBlocks(); blkIndex++) {
160 blockThyraToTpetra(numVectors, localData, leadingDim, prodX->getMultiVectorBlock(blkIndex),
178 void blockThyraToTpetra(
const Teuchos::RCP<
const Thyra::MultiVectorBase<ST> >& thyraX,
179 Tpetra::MultiVector<ST, LO, GO, NT>& tpetraX) {
181 LO numVectors = thyraX->domain()->dim();
184 TEUCHOS_ASSERT((
size_t)numVectors == tpetraX.getNumVectors());
185 TEUCHOS_ASSERT((Tpetra::global_size_t)thyraX->range()->dim() == tpetraX.getGlobalLength());
188 LO leadingDim = 0, localDim = 0;
189 leadingDim = tpetraX.getStride();
190 Teuchos::ArrayRCP<ST> tpetraData = tpetraX.get1dViewNonConst();
193 blockThyraToTpetra(numVectors, tpetraData, leadingDim, thyraX, localDim);
196 TEUCHOS_ASSERT((
size_t)localDim == tpetraX.getLocalLength());
199 void thyraVSToTpetraMap(std::vector<GO>& myIndicies,
int blockOffset,
200 const Thyra::VectorSpaceBase<ST>& vs,
int& localDim) {
204 const RCP<const Thyra::ProductVectorSpaceBase<ST> > prodVS =
205 rcp_dynamic_cast<
const Thyra::ProductVectorSpaceBase<ST> >(rcpFromRef(vs));
208 if (prodVS == Teuchos::null) {
212 const RCP<const Thyra::SpmdVectorSpaceBase<ST> > spmdVS =
213 rcp_dynamic_cast<
const Thyra::SpmdVectorSpaceBase<ST> >(rcpFromRef(vs));
214 TEUCHOS_TEST_FOR_EXCEPTION(spmdVS == Teuchos::null, std::runtime_error,
215 "thyraVSToTpetraMap requires all subblocks to be SPMD");
218 int localOffset = spmdVS->localOffset();
219 int localSubDim = spmdVS->localSubDim();
222 for (
int i = 0; i < localSubDim; i++) myIndicies.push_back(blockOffset + localOffset + i);
224 localDim += localSubDim;
230 for (
int blkIndex = 0; blkIndex < prodVS->numBlocks(); blkIndex++) {
234 thyraVSToTpetraMap(myIndicies, blockOffset, *prodVS->getBlock(blkIndex), subDim);
236 blockOffset += prodVS->getBlock(blkIndex)->dim();
244 const RCP<Tpetra::Map<LO, GO, NT> > thyraVSToTpetraMap(
245 const Thyra::VectorSpaceBase<ST>& vs,
246 const RCP<
const Teuchos::Comm<Thyra::Ordinal> >& ) {
248 std::vector<GO> myGIDs;
251 thyraVSToTpetraMap(myGIDs, 0, vs, localDim);
253 TEUCHOS_ASSERT(myGIDs.size() == (size_t)localDim);
259 return rcp(
new Tpetra::Map<LO, GO, NT>(vs.dim(), Teuchos::ArrayView<const GO>(myGIDs), 0,
260 Tpetra::getDefaultComm()));