Teko Version of the Day
Loading...
Searching...
No Matches
Teko_EpetraHelpers.cpp
1// @HEADER
2// *****************************************************************************
3// Teko: A package for block and physics based preconditioning
4//
5// Copyright 2010 NTESS and the Teko contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#include "Teko_EpetraHelpers.hpp"
11
12// Thyra Includes
13#include "Thyra_EpetraLinearOp.hpp"
14#include "Thyra_BlockedLinearOpBase.hpp"
15#include "Thyra_DefaultMultipliedLinearOp.hpp"
16#include "Thyra_DefaultDiagonalLinearOp.hpp"
17#include "Thyra_DefaultZeroLinearOp.hpp"
18#include "Thyra_DefaultBlockedLinearOp.hpp"
19#include "Thyra_EpetraThyraWrappers.hpp"
20#include "Thyra_SpmdVectorBase.hpp"
21#include "Thyra_SpmdVectorSpaceBase.hpp"
22#include "Thyra_ScalarProdVectorSpaceBase.hpp"
23
24// Epetra includes
25#include "Epetra_Vector.h"
26
27// EpetraExt includes
28#include "EpetraExt_ProductOperator.h"
29#include "EpetraExt_MatrixMatrix.h"
30
31// Teko includes
32#include "Teko_EpetraOperatorWrapper.hpp"
33#include "Teko_Utilities.hpp"
34
35using Teuchos::null;
36using Teuchos::RCP;
37using Teuchos::rcp;
38using Teuchos::rcp_dynamic_cast;
39using Teuchos::rcpFromRef;
40
41namespace Teko {
42namespace Epetra {
43
54const Teuchos::RCP<const Thyra::LinearOpBase<double> > thyraDiagOp(
55 const RCP<const Epetra_Vector>& ev, const Epetra_Map& map, const std::string& lbl) {
56 const RCP<const Thyra::VectorBase<double> > thyraVec // need a Thyra::VectorBase object
57 = Thyra::create_Vector(ev, Thyra::create_VectorSpace(rcpFromRef(map)));
58 Teuchos::RCP<Thyra::LinearOpBase<double> > op =
59 Teuchos::rcp(new Thyra::DefaultDiagonalLinearOp<double>(thyraVec));
60 op->setObjectLabel(lbl);
61 return op;
62}
63
74const Teuchos::RCP<Thyra::LinearOpBase<double> > thyraDiagOp(const RCP<Epetra_Vector>& ev,
75 const Epetra_Map& map,
76 const std::string& lbl) {
77 const RCP<Thyra::VectorBase<double> > thyraVec // need a Thyra::VectorBase object
78 = Thyra::create_Vector(ev, Thyra::create_VectorSpace(rcpFromRef(map)));
79 Teuchos::RCP<Thyra::LinearOpBase<double> > op =
80 Teuchos::rcp(new Thyra::DefaultDiagonalLinearOp<double>(thyraVec));
81 op->setObjectLabel(lbl);
82 return op;
83}
84
94void fillDefaultSpmdMultiVector(Teuchos::RCP<Thyra::DefaultSpmdMultiVector<double> >& spmdMV,
95 Teuchos::RCP<Epetra_MultiVector>& epetraMV) {
96 // first get desired range and domain
97 const RCP<const Thyra::SpmdVectorSpaceBase<double> > range = spmdMV->spmdSpace();
98 const RCP<const Thyra::ScalarProdVectorSpaceBase<double> > domain =
99 rcp_dynamic_cast<const Thyra::ScalarProdVectorSpaceBase<double> >(spmdMV->domain());
100
101 TEUCHOS_ASSERT(domain->dim() == epetraMV->NumVectors());
102
103 // New local view of raw data
104 double* localValues;
105 int leadingDim;
106 if (epetraMV->ConstantStride())
107 epetraMV->ExtractView(&localValues, &leadingDim);
108 else
109 TEUCHOS_TEST_FOR_EXCEPT(true); // ToDo: Implement views of non-contiguous mult-vectors!
110
111 // Build the MultiVector
112 spmdMV->initialize(range, domain,
113 Teuchos::arcp(localValues, 0, leadingDim * epetraMV->NumVectors(), false),
114 leadingDim);
115
116 // make sure the Epetra_MultiVector doesn't disappear prematurely
117 Teuchos::set_extra_data<RCP<Epetra_MultiVector> >(epetraMV, "Epetra_MultiVector",
118 Teuchos::outArg(spmdMV));
119}
120
130void identityRowIndices(const Epetra_Map& rowMap, const Epetra_CrsMatrix& mat,
131 std::vector<int>& outIndices) {
132 int maxSz = mat.GlobalMaxNumEntries();
133 std::vector<double> values(maxSz);
134 std::vector<int> indices(maxSz);
135
136 // loop over elements owned by this processor
137 for (int i = 0; i < rowMap.NumMyElements(); i++) {
138 bool rowIsIdentity = true;
139 int sz = 0;
140 int rowGID = rowMap.GID(i);
141 mat.ExtractGlobalRowCopy(rowGID, maxSz, sz, &values[0], &indices[0]);
142
143 // loop over the columns of this row
144 for (int j = 0; j < sz; j++) {
145 int colGID = indices[j];
146
147 // look at row entries
148 if (colGID == rowGID)
149 rowIsIdentity &= values[j] == 1.0;
150 else
151 rowIsIdentity &= values[j] == 0.0;
152
153 // not a dirchlet row...quit
154 if (not rowIsIdentity) break;
155 }
156
157 // save a row that is dirchlet
158 if (rowIsIdentity) outIndices.push_back(rowGID);
159 }
160}
161
172void zeroMultiVectorRowIndices(Epetra_MultiVector& mv, const std::vector<int>& zeroIndices) {
173 int colCnt = mv.NumVectors();
174 std::vector<int>::const_iterator itr;
175
176 // loop over the indices to zero
177 for (itr = zeroIndices.begin(); itr != zeroIndices.end(); ++itr) {
178 // loop over columns
179 for (int j = 0; j < colCnt; j++) TEUCHOS_TEST_FOR_EXCEPT(mv.ReplaceGlobalValue(*itr, j, 0.0));
180 }
181}
182
192ZeroedOperator::ZeroedOperator(const std::vector<int>& zeroIndices,
193 const Teuchos::RCP<const Epetra_Operator>& op)
194 : zeroIndices_(zeroIndices), epetraOp_(op) {
195 label_ = "zeroed( " + std::string(epetraOp_->Label()) + " )";
196}
197
199int ZeroedOperator::Apply(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const {
200 /*
201 Epetra_MultiVector temp(X);
202 zeroMultiVectorRowIndices(temp,zeroIndices_);
203 int result = epetraOp_->Apply(temp,Y);
204 */
205
206 int result = epetraOp_->Apply(X, Y);
207
208 // zero a few of the rows
209 zeroMultiVectorRowIndices(Y, zeroIndices_);
210
211 return result;
212}
213
214} // end namespace Epetra
215} // end namespace Teko
ZeroedOperator(const std::vector< int > &zeroIndices, const Teuchos::RCP< const Epetra_Operator > &op)
Constructor for a ZeroedOperator.
int Apply(const Epetra_MultiVector &X, Epetra_MultiVector &Y) const
Perform a matrix-vector product with certain rows zeroed out.