10 #include "Teko_EpetraThyraConverter.hpp"
13 #include "Teuchos_Array.hpp"
14 #include "Teuchos_ArrayRCP.hpp"
17 #include "Thyra_DefaultProductVectorSpace.hpp"
18 #include "Thyra_DefaultProductMultiVector.hpp"
19 #include "Thyra_SpmdMultiVectorBase.hpp"
20 #include "Thyra_SpmdVectorSpaceBase.hpp"
21 #include "Thyra_MultiVectorStdOps.hpp"
28 using Teuchos::ptr_dynamic_cast;
31 using Teuchos::rcp_dynamic_cast;
32 using Teuchos::rcpFromRef;
41 void blockEpetraToThyra(
int numVectors,
const double* epetraData,
int leadingDim,
42 const Teuchos::Ptr<Thyra::MultiVectorBase<double> >& mv,
int& localDim) {
46 const Ptr<Thyra::ProductMultiVectorBase<double> > prodMV =
47 ptr_dynamic_cast<Thyra::ProductMultiVectorBase<double> >(mv);
48 if (prodMV == Teuchos::null) {
50 const Ptr<Thyra::SpmdMultiVectorBase<double> > spmdX =
51 ptr_dynamic_cast<Thyra::SpmdMultiVectorBase<double> >(mv,
true);
52 const RCP<const Thyra::SpmdVectorSpaceBase<double> > spmdVS = spmdX->spmdSpace();
54 int localSubDim = spmdVS->localSubDim();
56 Thyra::Ordinal thyraLeadingDim = 0;
60 Teuchos::ArrayRCP<double> thyraData_arcp;
61 Teuchos::ArrayView<double> thyraData;
62 spmdX->getNonconstLocalData(Teuchos::outArg(thyraData_arcp), Teuchos::outArg(thyraLeadingDim));
63 thyraData = thyraData_arcp();
65 for (
int i = 0; i < localSubDim; i++) {
67 for (
int v = 0; v < numVectors; v++)
68 thyraData[i + thyraLeadingDim * v] = epetraData[i + leadingDim * v];
74 localDim = localSubDim;
80 const double* localData = epetraData;
83 for (
int blkIndex = 0; blkIndex < prodMV->productSpace()->numBlocks(); blkIndex++) {
85 const RCP<Thyra::MultiVectorBase<double> > blockVec =
86 prodMV->getNonconstMultiVectorBlock(blkIndex);
89 blockEpetraToThyra(numVectors, localData, leadingDim, blockVec.ptr(), subDim);
103 void blockEpetraToThyra(
const Epetra_MultiVector& epetraX,
104 const Teuchos::Ptr<Thyra::MultiVectorBase<double> >& thyraX) {
105 TEUCHOS_ASSERT(thyraX->range()->dim() == epetraX.GlobalLength());
108 int leadingDim = 0, numVectors = 0, localDim = 0;
109 double* epetraData = 0;
110 epetraX.ExtractView(&epetraData, &leadingDim);
112 numVectors = epetraX.NumVectors();
114 blockEpetraToThyra(numVectors, epetraData, leadingDim, thyraX.ptr(), localDim);
116 TEUCHOS_ASSERT(localDim == epetraX.MyLength());
119 void blockThyraToEpetra(
int numVectors,
double* epetraData,
int leadingDim,
120 const Teuchos::RCP<
const Thyra::MultiVectorBase<double> >& tX,
125 const RCP<const Thyra::ProductMultiVectorBase<double> > prodX =
126 rcp_dynamic_cast<
const Thyra::ProductMultiVectorBase<double> >(tX);
127 if (prodX == Teuchos::null) {
131 RCP<const Thyra::SpmdMultiVectorBase<double> > spmdX =
132 rcp_dynamic_cast<
const Thyra::SpmdMultiVectorBase<double> >(tX,
true);
133 RCP<const Thyra::SpmdVectorSpaceBase<double> > spmdVS = spmdX->spmdSpace();
135 int localSubDim = spmdVS->localSubDim();
137 Thyra::Ordinal thyraLeadingDim = 0;
141 Teuchos::ArrayView<const double> thyraData;
142 Teuchos::ArrayRCP<const double> thyraData_arcp;
143 spmdX->getLocalData(Teuchos::outArg(thyraData_arcp), Teuchos::outArg(thyraLeadingDim));
144 thyraData = thyraData_arcp();
146 for (
int i = 0; i < localSubDim; i++) {
148 for (
int v = 0; v < numVectors; v++)
149 epetraData[i + leadingDim * v] = thyraData[i + thyraLeadingDim * v];
153 localDim = localSubDim;
158 const RCP<const Thyra::ProductVectorSpaceBase<double> > prodVS = prodX->productSpace();
161 double* localData = epetraData;
164 for (
int blkIndex = 0; blkIndex < prodVS->numBlocks(); blkIndex++) {
168 blockThyraToEpetra(numVectors, localData, leadingDim, prodX->getMultiVectorBlock(blkIndex),
186 void blockThyraToEpetra(
const Teuchos::RCP<
const Thyra::MultiVectorBase<double> >& thyraX,
187 Epetra_MultiVector& epetraX) {
189 int numVectors = thyraX->domain()->dim();
192 TEUCHOS_ASSERT(numVectors == epetraX.NumVectors());
193 TEUCHOS_ASSERT(thyraX->range()->dim() == epetraX.GlobalLength());
196 int leadingDim = 0, localDim = 0;
197 double* epetraData = 0;
198 epetraX.ExtractView(&epetraData, &leadingDim);
201 blockThyraToEpetra(numVectors, epetraData, leadingDim, thyraX, localDim);
204 TEUCHOS_ASSERT(localDim == epetraX.Map().NumMyElements());
207 void thyraVSToEpetraMap(std::vector<int>& myIndicies,
int blockOffset,
208 const Thyra::VectorSpaceBase<double>& vs,
int& localDim) {
212 const RCP<const Thyra::ProductVectorSpaceBase<double> > prodVS =
213 rcp_dynamic_cast<
const Thyra::ProductVectorSpaceBase<double> >(rcpFromRef(vs));
216 if (prodVS == Teuchos::null) {
220 const RCP<const Thyra::SpmdVectorSpaceBase<double> > spmdVS =
221 rcp_dynamic_cast<
const Thyra::SpmdVectorSpaceBase<double> >(rcpFromRef(vs));
222 TEUCHOS_TEST_FOR_EXCEPTION(spmdVS == Teuchos::null, std::runtime_error,
223 "thyraVSToEpetraMap requires all subblocks to be SPMD");
226 int localOffset = spmdVS->localOffset();
227 int localSubDim = spmdVS->localSubDim();
230 for (
int i = 0; i < localSubDim; i++) myIndicies.push_back(blockOffset + localOffset + i);
232 localDim += localSubDim;
238 for (
int blkIndex = 0; blkIndex < prodVS->numBlocks(); blkIndex++) {
242 thyraVSToEpetraMap(myIndicies, blockOffset, *prodVS->getBlock(blkIndex), subDim);
244 blockOffset += prodVS->getBlock(blkIndex)->dim();
252 const RCP<Epetra_Map> thyraVSToEpetraMap(
const Thyra::VectorSpaceBase<double>& vs,
253 const RCP<const Epetra_Comm>& comm) {
255 std::vector<int> myGIDs;
258 thyraVSToEpetraMap(myGIDs, 0, vs, localDim);
260 TEUCHOS_ASSERT(myGIDs.size() == (
unsigned int)localDim);
263 return rcp(
new Epetra_Map(vs.dim(), myGIDs.size(), &(myGIDs[0]), 0, *comm));