Thyra Version of the Day
Loading...
Searching...
No Matches
Thyra_EpetraOperatorWrapper.cpp
1// @HEADER
2// *****************************************************************************
3// Thyra: Interfaces and Support for Abstract Numerical Algorithms
4//
5// Copyright 2004 NTESS and the Thyra contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#include "Thyra_EpetraOperatorWrapper.hpp"
12#include "Thyra_DetachedSpmdVectorView.hpp"
13#include "Thyra_DefaultProductVector.hpp"
14#include "Thyra_ProductVectorSpaceBase.hpp"
15#include "Thyra_SpmdVectorBase.hpp"
16#include "Thyra_EpetraLinearOp.hpp"
17
18#ifdef HAVE_MPI
19# include "Epetra_MpiComm.h"
20#endif
21#include "Epetra_SerialComm.h"
22#include "Epetra_Vector.h"
23
24#ifdef HAVE_MPI
25# include "Teuchos_DefaultMpiComm.hpp"
26#endif
27#include "Teuchos_DefaultSerialComm.hpp"
28
29
30namespace Thyra {
31
32
33// Constructor, utilties
34
35
37 const RCP<const LinearOpBase<double> > &thyraOp
38 )
39 : useTranspose_(false),
40 thyraOp_(thyraOp),
41 range_(thyraOp->range()),
42 domain_(thyraOp->domain()),
43 comm_(getEpetraComm(*thyraOp)),
44 rangeMap_(get_Epetra_Map(*range_, comm_)),
45 domainMap_(get_Epetra_Map(*domain_, comm_)),
46 label_(thyraOp->description())
47{;}
48
49
51 const Ptr<VectorBase<double> > &thyraVec) const
52{
53
54 using Teuchos::rcpFromPtr;
55 using Teuchos::rcp_dynamic_cast;
56
57 const int numVecs = x.NumVectors();
58
59 TEUCHOS_TEST_FOR_EXCEPTION(numVecs != 1, std::runtime_error,
60 "epetraToThyra does not work with MV dimension != 1");
61
62 const RCP<ProductVectorBase<double> > prodThyraVec =
63 castOrCreateNonconstProductVectorBase(rcpFromPtr(thyraVec));
64
65 const ArrayView<const double> epetraData(x[0], x.Map().NumMyElements());
66 // NOTE: I tried using Epetra_MultiVector::operator()(int) to return an
67 // Epetra_Vector object but it has a defect when Reset(...) is called which
68 // results in a memory access error (see bug 4700).
69
70 int offset = 0;
71 const int numBlocks = prodThyraVec->productSpace()->numBlocks();
72 for (int b = 0; b < numBlocks; ++b) {
73 const RCP<VectorBase<double> > vec_b = prodThyraVec->getNonconstVectorBlock(b);
75 rcp_dynamic_cast<const SpmdVectorSpaceBase<double> >(vec_b->space(), true);
77 const ArrayRCP<double> thyraData = view.sv().values();
78 const int localNumElems = spmd_vs_b->localSubDim();
79 for (int i=0; i < localNumElems; ++i) {
80 thyraData[i] = epetraData[i+offset];
81 }
82 offset += localNumElems;
83 }
84
85}
86
87
89 const VectorBase<double>& thyraVec, Epetra_MultiVector& x) const
90{
91
92 using Teuchos::rcpFromRef;
93 using Teuchos::rcp_dynamic_cast;
94
95 const int numVecs = x.NumVectors();
96
97 TEUCHOS_TEST_FOR_EXCEPTION(numVecs != 1, std::runtime_error,
98 "epetraToThyra does not work with MV dimension != 1");
99
100 const RCP<const ProductVectorBase<double> > prodThyraVec =
101 castOrCreateProductVectorBase(rcpFromRef(thyraVec));
102
103 const ArrayView<double> epetraData(x[0], x.Map().NumMyElements());
104 // NOTE: See above!
105
106 int offset = 0;
107 const int numBlocks = prodThyraVec->productSpace()->numBlocks();
108 for (int b = 0; b < numBlocks; ++b) {
109 const RCP<const VectorBase<double> > vec_b = prodThyraVec->getVectorBlock(b);
110 const RCP<const SpmdVectorSpaceBase<double> > spmd_vs_b =
111 rcp_dynamic_cast<const SpmdVectorSpaceBase<double> >(vec_b->space(), true);
113 const ArrayRCP<const double> thyraData = view.sv().values();
114 const int localNumElems = spmd_vs_b->localSubDim();
115 for (int i=0; i < localNumElems; ++i) {
116 epetraData[i+offset] = thyraData[i];
117 }
118 offset += localNumElems;
119 }
120
121}
122
123
124// Overridden from Epetra_Operator
125
126
128 Epetra_MultiVector& Y) const
129{
130
132 opRange = ( !useTranspose_ ? range_ : domain_ ),
133 opDomain = ( !useTranspose_ ? domain_ : range_ );
134
135 const RCP<VectorBase<double> > tx = createMember(opDomain);
136 copyEpetraIntoThyra(X, tx.ptr());
137
138 const RCP<VectorBase<double> > ty = createMember(opRange);
139
140 Thyra::apply<double>( *thyraOp_, !useTranspose_ ? NOTRANS : CONJTRANS, *tx, ty.ptr());
141
142 copyThyraIntoEpetra(*ty, Y);
143
144 return 0;
145
146}
147
148
150 Epetra_MultiVector& /* Y */) const
151{
152 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error,
153 "EpetraOperatorWrapper::ApplyInverse not implemented");
155}
156
157
159{
160 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error,
161 "EpetraOperatorWrapper::NormInf not implemated");
163}
164
165
166// private
167
168
170EpetraOperatorWrapper::getEpetraComm(const LinearOpBase<double>& thyraOp)
171{
172
173 using Teuchos::rcp;
174 using Teuchos::rcp_dynamic_cast;
176#ifdef HAVE_MPI
177 using Teuchos::MpiComm;
178#endif
179
181
183 rcp_dynamic_cast<const ProductVectorSpaceBase<double> >(vs);
184
185 if (nonnull(prod_vs))
186 vs = prod_vs->getBlock(0);
187
189 rcp_dynamic_cast<const SpmdVectorSpaceBase<double> >(vs, true);
190
191 return get_Epetra_Comm(*spmd_vs->getComm());
192
193}
194
195
196} // namespace Thyra
197
198
200Thyra::makeEpetraWrapper(const RCP<const LinearOpBase<double> > &thyraOp)
201{
202 return epetraLinearOp(
203 Teuchos::rcp(new EpetraOperatorWrapper(thyraOp))
204 );
205}
int NumMyElements() const
const Epetra_BlockMap & Map() const
int NumVectors() const
Ptr< T > ptr() const
Create an explicit detached non-mutable (const) view of all of the local elements on this process of ...
Create an explicit detached mutable (non-const) view of all of the local elements on this process of ...
void copyEpetraIntoThyra(const Epetra_MultiVector &x, const Ptr< VectorBase< double > > &thyraVec) const
int ApplyInverse(const Epetra_MultiVector &X, Epetra_MultiVector &Y) const
EpetraOperatorWrapper(const RCP< const LinearOpBase< double > > &thyraOp)
void copyThyraIntoEpetra(const VectorBase< double > &thyraVec, Epetra_MultiVector &x) const
int Apply(const Epetra_MultiVector &X, Epetra_MultiVector &Y) const
Base class for all linear operators.
virtual RCP< const VectorSpaceBase< Scalar > > range() const =0
Return a smart pointer for the range space for this operator.
Abstract interface for finite-dimensional dense vectors.
RCP< const Epetra_Comm > get_Epetra_Comm(const Teuchos::Comm< Ordinal > &comm)
Get (or create) and Epetra_Comm given a Teuchos::Comm object.
RCP< const Epetra_Map > get_Epetra_Map(const VectorSpaceBase< double > &vs, const RCP< const Epetra_Comm > &comm)
Get (or create) an Epetra_Map object given an VectorSpaceBase object an optionally an extra Epetra_Co...
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
@ NOTRANS
Use the non-transposed operator.
@ CONJTRANS
Use the transposed operator with complex-conjugate clements (same as TRANS for real scalar types).
#define TEUCHOS_UNREACHABLE_RETURN(dummyReturnVal)
T_To & dyn_cast(T_From &from)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)