Belos Version of the Day
Loading...
Searching...
No Matches
BelosFGCRODRIter.hpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// Belos: Block Linear Solvers Package
4//
5// Copyright 2004-2016 NTESS and the Belos contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#ifndef BELOS_FGCRODR_ITER_HPP
11#define BELOS_FGCRODR_ITER_HPP
12
17#include "BelosGCRODRIter.hpp"
18
19namespace Belos {
20
26
32
33template<class ScalarType, class MV, class OP, class DM = DefaultDenseMatrix<int, ScalarType> >
34class FGCRODRIter : virtual public GCRODRIteration<ScalarType,MV,OP,DM> {
35public:
39 typedef Teuchos::ScalarTraits<ScalarType> SCT;
40 typedef typename SCT::magnitudeType MagnitudeType;
41
43 const Teuchos::RCP<OutputManager<ScalarType> > &printer,
44 const Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> > &tester,
45 const Teuchos::RCP<MatOrthoManager<ScalarType,MV,OP,DM> > &ortho,
46 Teuchos::ParameterList &params);
47
48 virtual ~FGCRODRIter() {}
49
50 void iterate();
51
53
58
61 state.curDim = curDim_;
62 state.V = V_;
63 state.Z = Z_;
64 state.U = U_;
65 state.C = C_;
66 state.H2 = H2_;
67 state.H = H_;
68 state.B = B_;
69 return state;
70 }
71
72 int getNumIters() const { return iter_; }
73
74 void resetNumIters(int iter = 0) { iter_ = iter; }
75
76 Teuchos::RCP<const MV>
77 getNativeResiduals(std::vector<MagnitudeType> *norms) const;
78
79 Teuchos::RCP<MV> getCurrentUpdate() const;
80
81 void updateLSQR(int dim = -1);
82
83 int getCurSubspaceDim() const {
84 if (!initialized_) return 0;
85 return curDim_;
86 }
87
88 int getMaxSubspaceDim() const { return numBlocks_; }
89
91 return *lp_;
92 }
93
94 int getNumBlocks() const { return numBlocks_; }
95
97 setSize(recycledBlocks_, numBlocks);
98 }
99
100 int getBlockSize() const { return 1; }
101
104 blockSize != 1,
105 std::invalid_argument,
106 "Belos::FGCRODRIter::setBlockSize(): Cannot use a block size that is not one.");
107 }
108
110 if (recycledBlocks_ != recycledBlocks)
111 recycledBlocks_ = recycledBlocks;
112
113 if (numBlocks_ != numBlocks) {
114 numBlocks_ = numBlocks;
115 cs_.resize(numBlocks_ + 1);
116 sn_.resize(numBlocks_ + 1);
117 z_ = DMT::Create(numBlocks_ + 1, 1, false);
118 R_ = DMT::Create(numBlocks_ + 1, numBlocks_, false);
119 }
120 }
121
122 bool isInitialized() { return initialized_; }
123
124private:
125 const Teuchos::RCP<LinearProblem<ScalarType,MV,OP,DM> > lp_;
126 const Teuchos::RCP<OutputManager<ScalarType> > om_;
127 const Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> > stest_;
128 const Teuchos::RCP<OrthoManager<ScalarType,MV,DM> > ortho_;
129
130 int numBlocks_;
131 int recycledBlocks_;
132
133 std::vector<ScalarType> sn_;
134 std::vector<MagnitudeType> cs_;
135
136 bool initialized_;
137 int curDim_, iter_;
138 int ptrH00_;
139
140 Teuchos::RCP<MV> V_;
141 Teuchos::RCP<MV> Z_;
142 Teuchos::RCP<MV> U_, C_;
143
144 Teuchos::RCP<DM> H2_;
145 Teuchos::RCP<DM> H_;
146 Teuchos::RCP<DM> B_;
147
148 Teuchos::RCP<DM> R_;
149 Teuchos::RCP<DM> z_;
150};
151
152
153// Constructor
154template<class ScalarType, class MV, class OP, class DM>
157 const Teuchos::RCP<OutputManager<ScalarType> > &printer,
158 const Teuchos::RCP<StatusTest<ScalarType,MV,OP,DM> > &tester,
159 const Teuchos::RCP<MatOrthoManager<ScalarType,MV,OP,DM> > &ortho,
160 Teuchos::ParameterList &params) :
161 lp_(problem),
162 om_(printer),
163 stest_(tester),
164 ortho_(ortho),
165 numBlocks_(0),
166 recycledBlocks_(0),
167 initialized_(false),
168 curDim_(0),
169 iter_(0),
170 ptrH00_(0),
171 V_(Teuchos::null),
172 Z_(Teuchos::null),
173 U_(Teuchos::null),
174 C_(Teuchos::null),
175 H2_(Teuchos::null),
176 H_(Teuchos::null),
177 B_(Teuchos::null)
178{
180 !params.isParameter("Num Blocks"),
181 std::invalid_argument,
182 "Belos::FGCRODRIter::constructor: mandatory parameter \"Num Blocks\" is not specified.");
183 int nb = Teuchos::getParameter<int>(params, "Num Blocks");
184
186 !params.isParameter("Recycled Blocks"),
187 std::invalid_argument,
188 "Belos::FGCRODRIter::constructor: mandatory parameter \"Recycled Blocks\" is not specified.");
189 int rb = Teuchos::getParameter<int>(params, "Recycled Blocks");
190
192 nb <= 0,
193 std::invalid_argument,
194 "Belos::FGCRODRIter() was passed a non-positive argument for \"Num Blocks\".");
195
197 rb >= nb,
198 std::invalid_argument,
199 "Belos::FGCRODRIter() the number of recycled blocks is larger than the allowable subspace.");
200
201 numBlocks_ = nb;
202 recycledBlocks_ = rb;
203
204 cs_.resize(numBlocks_ + 1);
205 sn_.resize(numBlocks_ + 1);
206 z_ = DMT::Create(numBlocks_ + 1, 1, false);
207 R_ = DMT::Create(numBlocks_ + 1, numBlocks_, false);
208}
209
210
211// Get current flexible update.
212template<class ScalarType, class MV, class OP, class DM>
213Teuchos::RCP<MV>
215{
216 Teuchos::RCP<MV> currentUpdate = Teuchos::null;
217
218 if (curDim_ == 0) {
219 return currentUpdate;
220 }
221
222 const ScalarType one = SCT::one();
223 const ScalarType zero = SCT::zero();
224
225 Teuchos::BLAS<int,ScalarType> blas;
226
227 currentUpdate = MVT::Clone(*Z_, 1);
228
229 Teuchos::RCP<DM> y = DMT::SubviewCopy(*z_, curDim_, 1);
230
231 DMT::SyncDeviceToHost(*y);
232 DMT::SyncDeviceToHost(*R_);
233
234 blas.TRSM(Teuchos::LEFT_SIDE,
235 Teuchos::UPPER_TRI,
236 Teuchos::NO_TRANS,
237 Teuchos::NON_UNIT_DIAG,
238 curDim_,
239 1,
240 one,
241 DMT::GetConstRawHostPtr(*R_),
242 DMT::GetStride(*R_),
243 DMT::GetRawHostPtr(*y),
244 DMT::GetStride(*y));
245
246 DMT::SyncHostToDevice(*y);
247
248 // Flexible part: update = Z(:,1:curDim) * y.
249 std::vector<int> index(curDim_);
250 for (int i = 0; i < curDim_; ++i) {
251 index[i] = i;
252 }
253
254 Teuchos::RCP<const MV> Zjp1 = MVT::CloneView(*Z_, index);
255 MVT::MvTimesMatAddMv(one, *Zjp1, *y, zero, *currentUpdate);
256
257 // Recycle correction: update -= U * B * y.
258 if (U_ != Teuchos::null) {
259 Teuchos::RCP<DM> z = DMT::Create(recycledBlocks_, 1);
260
261 DMT::SyncDeviceToHost(*H2_);
262
263 blas.GEMM(Teuchos::NO_TRANS,
264 Teuchos::NO_TRANS,
265 recycledBlocks_,
266 1,
267 curDim_,
268 one,
269 DMT::GetConstRawHostPtr(*B_),
270 DMT::GetStride(*B_),
271 DMT::GetConstRawHostPtr(*y),
272 DMT::GetStride(*y),
273 zero,
274 DMT::GetRawHostPtr(*z),
275 DMT::GetStride(*z));
276
277 DMT::SyncHostToDevice(*z);
278
279 MVT::MvTimesMatAddMv(-one, *U_, *z, one, *currentUpdate);
280 }
281
282 return currentUpdate;
283}
284
285
286// Native residual norms.
287template<class ScalarType, class MV, class OP, class DM>
288Teuchos::RCP<const MV>
290getNativeResiduals(std::vector<MagnitudeType> *norms) const
291{
292 if (norms && static_cast<int>(norms->size()) == 0) {
293 norms->resize(1);
294 }
295
296 if (norms) {
297 DMT::SyncDeviceToHost(*z_);
298 const ScalarType curNativeResid = DMT::ValueConst(*z_, curDim_, 0);
299 (*norms)[0] = SCT::magnitude(curNativeResid);
300 }
301
302 return Teuchos::null;
303}
304
305
306// Initialize.
307template<class ScalarType, class MV, class OP, class DM>
308void
311{
312 if (newstate.V != Teuchos::null &&
313 newstate.Z != Teuchos::null &&
314 newstate.H2 != Teuchos::null) {
315 curDim_ = newstate.curDim;
316 V_ = newstate.V;
317 Z_ = newstate.Z;
318 U_ = newstate.U;
319 C_ = newstate.C;
320 H2_ = newstate.H2;
321
322 // No recycled space; this cycle primes the recycle space.
323 if (newstate.U == Teuchos::null) {
324 ptrH00_ = recycledBlocks_ + 1;
325 H_ = DMT::Subview(*H2_, numBlocks_ + 1, numBlocks_, ptrH00_, ptrH00_);
326 B_ = Teuchos::null;
327 }
328 else {
329 ptrH00_ = recycledBlocks_;
330 H_ = DMT::Subview(*H2_, numBlocks_ + 1, numBlocks_, ptrH00_, ptrH00_);
331 B_ = DMT::Subview(*H2_, recycledBlocks_, numBlocks_, 0, ptrH00_);
332 }
333 }
334 else {
336 newstate.V == Teuchos::null,
337 std::invalid_argument,
338 "Belos::FGCRODRIter::initialize(): GCRODRIterState does not have V initialized.");
340 newstate.Z == Teuchos::null,
341 std::invalid_argument,
342 "Belos::FGCRODRIter::initialize(): GCRODRIterState does not have Z initialized.");
344 newstate.H2 == Teuchos::null,
345 std::invalid_argument,
346 "Belos::FGCRODRIter::initialize(): GCRODRIterState does not have H2 initialized.");
347 }
348
349 initialized_ = true;
350}
351
352
353// Iterate.
354template<class ScalarType, class MV, class OP, class DM>
355void
357{
359 initialized_ == false,
361 "Belos::FGCRODRIter::iterate(): FGCRODRIter class not initialized.");
362
363 setSize(recycledBlocks_, numBlocks_);
364
365 Teuchos::RCP<MV> Vnext;
366 Teuchos::RCP<MV> Znext;
367 Teuchos::RCP<const MV> Vprev;
368
369 std::vector<int> curind(1);
370
371 DMT::PutScalar(*z_);
372
373 // Orthonormalize the initial residual vector in V(:,0).
374 curind[0] = 0;
375 Vnext = MVT::CloneViewNonConst(*V_, curind);
376
377 Teuchos::RCP<DM> z0 = DMT::Subview(*z_, 1, 1);
378 int rank = ortho_->normalize(*Vnext, z0);
379
381 rank != 1,
383 "Belos::FGCRODRIter::iterate(): couldn't generate initial basis of full rank.");
384
385 std::vector<int> prevind(numBlocks_ + 1);
386
387 while (stest_->checkStatus(this) != Passed && curDim_ + 1 <= numBlocks_) {
388 iter_++;
389
390 const int lclDim = curDim_ + 1;
391
392 // Next V basis vector storage.
393 curind[0] = lclDim;
394 Vnext = MVT::CloneViewNonConst(*V_, curind);
395
396 // Current V vector.
397 curind[0] = curDim_;
398 Vprev = MVT::CloneView(*V_, curind);
399
400 // Current flexible correction vector.
401 Znext = MVT::CloneViewNonConst(*Z_, curind);
402
403 // z_j = M_j(v_j). If no right preconditioner exists,
404 // LinearProblem::applyRightPrec copies v_j into z_j.
405 lp_->applyRightPrec(*Vprev, *Znext);
406 Vprev = Teuchos::null;
407
408 // w = A z_j.
409 lp_->applyOp(*Znext, *Vnext);
410 Znext = Teuchos::null;
411
412 if (U_ != Teuchos::null) {
413 DMT::SyncHostToDevice(*H2_);
414
415 // Project out recycled image space C and store coefficients in B.
416 Teuchos::Array<Teuchos::RCP<const MV> > C(1, C_);
417 Teuchos::RCP<DM> subB =
418 DMT::Subview(*H2_, recycledBlocks_, 1, 0, ptrH00_ + curDim_);
419 Teuchos::Array<Teuchos::RCP<DM> > AsubB(1, subB);
420
421 ortho_->project(*Vnext, AsubB, C);
422 }
423
424 // Orthogonalize against previous Krylov basis vectors.
425 prevind.resize(lclDim);
426 for (int i = 0; i < lclDim; ++i) {
427 prevind[i] = i;
428 }
429
430 Vprev = MVT::CloneView(*V_, prevind);
431 Teuchos::Array<Teuchos::RCP<const MV> > AVprev(1, Vprev);
432
433 Teuchos::RCP<DM> subH =
434 DMT::Subview(*H2_, lclDim, 1, ptrH00_, ptrH00_ + curDim_);
435 Teuchos::Array<Teuchos::RCP<DM> > AsubH(1, subH);
436
437 Teuchos::RCP<DM> subR =
438 DMT::Subview(*H2_, 1, 1, ptrH00_ + lclDim, ptrH00_ + curDim_);
439
440 rank = ortho_->projectAndNormalize(*Vnext, AsubH, subR, AVprev);
441
442 Teuchos::RCP<DM> subR2 =
443 DMT::Subview(*R_, lclDim + 1, 1, 0, curDim_);
444 Teuchos::RCP<const DM> subH2 =
445 DMT::SubviewConst(*H2_, lclDim + 1, 1, ptrH00_, ptrH00_ + curDim_);
446
447 DMT::Assign(*subR2, *subH2);
448
450 rank != 1,
452 "Belos::FGCRODRIter::iterate(): couldn't generate basis of full rank.");
453
454 updateLSQR();
455
456 curDim_++;
457 }
458}
459
460
461// Update QR factorization.
462template<class ScalarType, class MV, class OP, class DM>
463void
465{
466 int i;
467 const ScalarType zero = SCT::zero();
468
469 int curDim = curDim_;
470 if ((dim >= curDim_) && (dim < getMaxSubspaceDim())) {
471 curDim = dim;
472 }
473
474 Teuchos::BLAS<int, ScalarType> blas;
475
476 DMT::SyncDeviceToHost(*R_);
477 DMT::SyncDeviceToHost(*z_);
478
479 for (i = 0; i < curDim; ++i) {
480 blas.ROT(1,
481 &(DMT::Value(*R_, i, curDim)),
482 1,
483 &(DMT::Value(*R_, i+1, curDim)),
484 1,
485 &cs_[i],
486 &sn_[i]);
487 }
488
489 blas.ROTG(&(DMT::Value(*R_, curDim, curDim)),
490 &(DMT::Value(*R_, curDim+1, curDim)),
491 &cs_[curDim],
492 &sn_[curDim]);
493
494 DMT::Value(*R_, curDim+1, curDim) = zero;
495
496 blas.ROT(1,
497 &(DMT::Value(*z_, curDim, 0)),
498 1,
499 &(DMT::Value(*z_, curDim+1, 0)),
500 1,
501 &cs_[curDim],
502 &sn_[curDim]);
503
504 DMT::SyncHostToDevice(*R_);
505 DMT::SyncHostToDevice(*z_);
506}
507
508} // namespace Belos
509
510#endif // BELOS_FGCRODR_ITER_HPP
Belos concrete class for performing the GCRO-DR iteration.
GCRODRIterState< ScalarType, MV, DM > getState() const
const LinearProblem< ScalarType, MV, OP, DM > & getProblem() const
Get a constant reference to the linear problem.
void setSize(int recycledBlocks, int numBlocks)
MultiVecTraits< ScalarType, MV, DM > MVT
int getBlockSize() const
Get the blocksize to be used by the iterative solver in solving this linear problem.
Teuchos::RCP< const MV > getNativeResiduals(std::vector< MagnitudeType > *norms) const
SCT::magnitudeType MagnitudeType
Teuchos::ScalarTraits< ScalarType > SCT
OperatorTraits< ScalarType, MV, OP > OPT
Teuchos::RCP< MV > getCurrentUpdate() const
Get the current update to the linear system.
int getCurSubspaceDim() const
void resetNumIters(int iter=0)
Reset the iteration count to iter.
int getNumIters() const
Get the current iteration count.
int getMaxSubspaceDim() const
void updateLSQR(int dim=-1)
void setBlockSize(int blockSize)
Set the blocksize to be used by the iterative solver in solving this linear problem.
void iterate()
This method performs linear solver iterations until the status test indicates the need to stop or an ...
void setNumBlocks(int numBlocks)
DenseMatTraits< ScalarType, DM > DMT
void initialize()
Initialize the solver with the initial vectors from the linear problem or random data.
bool isInitialized()
States whether the solver has been initialized or not.
FGCRODRIter(const Teuchos::RCP< LinearProblem< ScalarType, MV, OP, DM > > &problem, const Teuchos::RCP< OutputManager< ScalarType > > &printer, const Teuchos::RCP< StatusTest< ScalarType, MV, OP, DM > > &tester, const Teuchos::RCP< MatOrthoManager< ScalarType, MV, OP, DM > > &ortho, Teuchos::ParameterList &params)
FGCRODRIterInitFailure(const std::string &what_arg)
FGCRODRIterOrthoFailure(const std::string &what_arg)
GCRODRIterInitFailure is thrown when the GCRODRIter object is unable to generate an initial iterate i...
GCRODRIterOrthoFailure is thrown when the GCRODRIter object is unable to compute independent directio...
Common base interface for GCRODRIter and FGCRODRIter.
Alternative run-time polymorphic interface for operators.
Operator()
Default constructor (does nothing).

Generated for Belos by doxygen 1.9.8