Teko Version of the Day
Loading...
Searching...
No Matches
Teko_BlockedMappingStrategy.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 "Epetra/Teko_BlockedMappingStrategy.hpp"
11#include "Epetra/Teko_EpetraHelpers.hpp"
12
13#include "Thyra_EpetraThyraWrappers.hpp"
14#include "Thyra_EpetraLinearOp.hpp"
15#include "Thyra_DefaultProductMultiVector.hpp"
16#include "Thyra_DefaultProductVectorSpace.hpp"
17#include "Thyra_DefaultSpmdMultiVector.hpp"
18#include "Thyra_DefaultBlockedLinearOp.hpp"
19#include "Thyra_get_Epetra_Operator.hpp"
20
21using Teuchos::RCP;
22using Teuchos::rcp;
23using Teuchos::rcp_dynamic_cast;
24
25namespace Teko {
26namespace Epetra {
27
28// Creates a strided mapping strategy. This class is useful
29// for breaking up nodally ordered matrices (i.e. the unknowns
30// in a FEM problem are ordered [u0,v0,p0,u1,v1,p1,...]). Current
31// implimentation only supports a fixed number of variables
32//
33// arguments:
34// vars - Number of different variables
35// map - original Epetra_Map to be broken up
36// comm - Epetra_Comm object related to the map
37//
38BlockedMappingStrategy::BlockedMappingStrategy(const std::vector<std::vector<int> >& vars,
39 const Teuchos::RCP<const Epetra_Map>& map,
40 const Epetra_Comm& comm) {
41 rangeMap_ = map;
42 domainMap_ = map;
43 buildBlockTransferData(vars, rangeMap_, comm);
44}
45
46// Virtual function defined in MappingStrategy. This copies
47// an Epetra_MultiVector into a Thyra::MultiVectorBase with
48// blocking handled by the strides defined in the constructor.
49//
50// arguments:
51// X - source Epetra_MultiVector
52// thyra_X - destination Thyra::MultiVectorBase
53//
54void BlockedMappingStrategy::copyEpetraIntoThyra(
55 const Epetra_MultiVector& X,
56 const Teuchos::Ptr<Thyra::MultiVectorBase<double> >& thyra_X) const {
57 int count = X.NumVectors();
58
59 std::vector<RCP<Epetra_MultiVector> > subX;
60
61 // allocate vectors to copy into
62 Blocking::buildSubVectors(blockMaps_, subX, count);
63
64 // copy source vector to X vector
65 Blocking::one2many(subX, X, blockImport_);
66
67 // convert subX to an array of multi vectors
68 Teuchos::Array<RCP<Thyra::MultiVectorBase<double> > > thyra_subX;
69 Teuchos::Ptr<Thyra::ProductMultiVectorBase<double> > prod_X =
70 Teuchos::ptr_dynamic_cast<Thyra::ProductMultiVectorBase<double> >(thyra_X);
71 for (unsigned int i = 0; i < blockMaps_.size(); i++) {
72 RCP<Thyra::DefaultSpmdMultiVector<double> > vec =
73 rcp_dynamic_cast<Thyra::DefaultSpmdMultiVector<double> >(
74 prod_X->getNonconstMultiVectorBlock(i));
75 fillDefaultSpmdMultiVector(vec, subX[i]);
76 }
77}
78
79// Virtual function defined in MappingStrategy. This copies
80// an Epetra_MultiVector into a Thyra::MultiVectorBase with
81// blocking handled by the strides defined in the constructor.
82//
83// arguments:
84// thyra_Y - source Thyra::MultiVectorBase
85// Y - destination Epetra_MultiVector
86//
87void BlockedMappingStrategy::copyThyraIntoEpetra(
88 const RCP<const Thyra::MultiVectorBase<double> >& thyra_Y, Epetra_MultiVector& Y) const {
89 std::vector<RCP<const Epetra_MultiVector> > subY;
90 RCP<const Thyra::DefaultProductMultiVector<double> > prod_Y =
91 rcp_dynamic_cast<const Thyra::DefaultProductMultiVector<double> >(thyra_Y);
92
93 // convert thyra product vector to subY
94 for (unsigned int i = 0; i < blockMaps_.size(); i++)
95 subY.push_back(
96 Thyra::get_Epetra_MultiVector(*blockMaps_[i].second, prod_Y->getMultiVectorBlock(i)));
97
98 // endow the subVectors with required information about the maps
99 // Blocking::associateSubVectors(blockMaps_,subY);
100
101 // copy solution vectors to Y vector
102 Blocking::many2one(Y, subY, blockExport_);
103}
104
105// this is the core routine that builds the maps
106// and importers/exporters neccessary for all the
107// transfers. Currently it simply calls out to the
108// interlaced epetra functions. (Comment: this
109// routine should probably be private or protected
110// ... it is basically the meat of the constructor)
111//
112// arguments:
113// vars - Vector describing the blocking of variables
114// baseMap - basic map to use in the transfers
115// comm - Epetra_Comm object
116//
117void BlockedMappingStrategy::buildBlockTransferData(const std::vector<std::vector<int> >& vars,
118 const Teuchos::RCP<const Epetra_Map>& baseMap,
119 const Epetra_Comm& comm) {
120 // build block for each vector
121 for (std::size_t i = 0; i < vars.size(); i++) {
122 // build maps and exporters/importers
123 Blocking::MapPair mapPair = Blocking::buildSubMap(vars[i], comm);
124 Blocking::ImExPair iePair = Blocking::buildExportImport(*baseMap, mapPair);
125
126 blockMaps_.push_back(mapPair);
127 blockImport_.push_back(iePair.first);
128 blockExport_.push_back(iePair.second);
129 }
130}
131
132// Builds a blocked Thyra operator that uses the strided
133// mapping strategy to define sub blocks.
134//
135// arguments:
136// mat - Epetra_CrsMatrix with FillComplete called, this
137// matrix is assumed to be square, with the same
138// range and domain maps
139// returns: Blocked Thyra linear operator with sub blocks
140// defined by this mapping strategy
141//
142const Teuchos::RCP<Thyra::BlockedLinearOpBase<double> > BlockedMappingStrategy::buildBlockedThyraOp(
143 const RCP<const Epetra_CrsMatrix>& crsContent, const std::string& label) const {
144 int dim = blockMaps_.size();
145
146 RCP<Thyra::DefaultBlockedLinearOp<double> > A = Thyra::defaultBlockedLinearOp<double>();
147
148 A->beginBlockFill(dim, dim);
149 for (int i = 0; i < dim; i++) {
150 for (int j = 0; j < dim; j++) {
151 // label block correctly
152 std::stringstream ss;
153 ss << label << "_" << i << "," << j;
154
155 // build the blocks and place it the right location
156 RCP<Epetra_CrsMatrix> blk = Blocking::buildSubBlock(i, j, *crsContent, blockMaps_);
157 A->setNonconstBlock(i, j, Thyra::nonconstEpetraLinearOp(blk, ss.str()));
158 }
159 } // end for i
160 A->endBlockFill();
161
162 return A;
163}
164
165// Rebuilds a blocked Thyra operator that uses the strided
166// mapping strategy to define sub blocks.
167//
168// arguments:
169// crsContent - Epetra_CrsMatrix with FillComplete called, this
170// matrix is assumed to be square, with the same
171// range and domain maps
172// A - Destination block linear op composed of blocks of
173// Epetra_CrsMatrix at all relevant locations
174//
175void BlockedMappingStrategy::rebuildBlockedThyraOp(
176 const RCP<const Epetra_CrsMatrix>& crsContent,
177 const RCP<Thyra::BlockedLinearOpBase<double> >& A) const {
178 int dim = blockMaps_.size();
179
180 for (int i = 0; i < dim; i++) {
181 for (int j = 0; j < dim; j++) {
182 // get Epetra version of desired block
183 RCP<Thyra::LinearOpBase<double> > Aij = A->getNonconstBlock(i, j);
184 RCP<Epetra_CrsMatrix> eAij =
185 rcp_dynamic_cast<Epetra_CrsMatrix>(Thyra::get_Epetra_Operator(*Aij), true);
186
187 // rebuild the blocks and place it the right location
188 Blocking::rebuildSubBlock(i, j, *crsContent, blockMaps_, *eAij);
189 }
190 } // end for i
191}
192
193} // end namespace Epetra
194} // end namespace Teko