81 typedef Teuchos::ScalarTraits<ScalarType>
SCT;
83 typedef Teuchos::ScalarTraits<MagnitudeType>
MT;
91 replacementStrategy_(
"Restart"),
93 reorthogonalizationSteps_(2),
102 const Teuchos::RCP<Teuchos::ParameterList>&
params) :
106 replacementStrategy_(
"Restart"),
108 reorthogonalizationSteps_(2),
114 params->get(
"Maximum Basis Size", maxBasisSize_);
115 replacementStrategy_ =
116 params->get(
"Replacement Strategy", replacementStrategy_);
118 params->get(
"Projection Tolerance", projectionTol_);
119 reorthogonalizationSteps_ =
120 params->get(
"Reorthogonalization Steps", reorthogonalizationSteps_);
123 validateParameters();
143 return curBasisSize_;
148 return maxBasisSize_;
154 validateParameters();
159 return replacementStrategy_;
164 projectionTol_ =
tol;
165 validateParameters();
170 return projectionTol_;
175 reorthogonalizationSteps_ =
steps;
176 validateParameters();
181 return reorthogonalizationSteps_;
186 if (curBasisSize_ == 0 || U_.is_null()) {
187 return Teuchos::null;
190 std::vector<int>
ind(curBasisSize_);
191 for (
int i = 0;
i < curBasisSize_; ++
i) {
195 return MVT::CloneView(*U_,
ind);
200 if (curBasisSize_ == 0 || C_.is_null()) {
201 return Teuchos::null;
204 std::vector<int>
ind(curBasisSize_);
205 for (
int i = 0;
i < curBasisSize_; ++
i) {
209 return MVT::CloneView(*C_,
ind);
217 "Belos::SolutionProjection::addSolution(): operator is null.");
219 const int numVecs = MVT::GetNumberVecs(
u);
223 std::invalid_argument,
224 "Belos::SolutionProjection::addSolution(): input multivector must contain at least one vector.");
226 Teuchos::RCP<MV>
c = MVT::Clone(
u,
numVecs);
235 const int numVecs = MVT::GetNumberVecs(
u);
239 std::invalid_argument,
240 "Belos::SolutionProjection::addPair(): input multivector must contain at least one vector.");
244 std::invalid_argument,
245 "Belos::SolutionProjection::addPair(): u and c must have the same number of vectors.");
248 MVT::GetGlobalLength(
u) != MVT::GetGlobalLength(
c),
249 std::invalid_argument,
250 "Belos::SolutionProjection::addPair(): u and c must have the same global length.");
252 if (maxBasisSize_ == 0) {
261 std::vector<int>
srcInd(1);
264 Teuchos::RCP<const MV>
uSrc = MVT::CloneView(
u,
srcInd);
265 Teuchos::RCP<const MV>
cSrc = MVT::CloneView(
c,
srcInd);
267 Teuchos::RCP<MV>
uNew = MVT::CloneCopy(*
uSrc);
268 Teuchos::RCP<MV>
cNew = MVT::CloneCopy(*
cSrc);
281 if (curBasisSize_ == 0) {
285 validateProjectionInputs(
x, r);
289 const int numRhs = MVT::GetNumberVecs(r);
291 std::vector<int>
ind(curBasisSize_);
292 for (
int i = 0;
i < curBasisSize_; ++
i) {
296 Teuchos::RCP<const MV>
Ucur = MVT::CloneView(*U_,
ind);
297 Teuchos::RCP<const MV>
Ccur = MVT::CloneView(*C_,
ind);
299 Teuchos::RCP<DM>
gamma = DMT::Create(curBasisSize_,
numRhs);
318 "Belos::SolutionProjection::project(): operator is null.");
320 validateProjectionInputs(
x,
b);
325 std::invalid_argument,
326 "Belos::SolutionProjection::project(): projectedResidual must have the same number of vectors as b.");
330 std::invalid_argument,
331 "Belos::SolutionProjection::project(): projectedResidual must have the same global length as b.");
334 Teuchos::RCP<MV> r = MVT::Clone(
b, MVT::GetNumberVecs(
b));
337 MVT::MvAddMv(-SCT::one(), *r, SCT::one(),
b, *r);
349 Teuchos::RCP<MV>
x =
problem.getCurrLHSVec();
354 "Belos::SolutionProjection::project(LinearProblem): current LHS is null. "
355 "Did you call setLSIndex() or otherwise set the current linear system?");
357 Teuchos::RCP<const MV>
b =
problem.getCurrRHSVec();
362 "Belos::SolutionProjection::project(LinearProblem): current RHS is null. "
363 "Did you call setLSIndex() or otherwise set the current linear system?");
368 std::invalid_argument,
369 "Belos::SolutionProjection::project(LinearProblem): projectedResidual has wrong number of vectors.");
373 std::invalid_argument,
374 "Belos::SolutionProjection::project(LinearProblem): projectedResidual has wrong global length.");
377 Teuchos::RCP<MV> r = MVT::Clone(*
b, MVT::GetNumberVecs(*
b));
380 problem.computeCurrResVec(&*r);
390 void validateParameters()
const {
393 std::invalid_argument,
394 "Belos::SolutionProjection: maximum basis size must be nonnegative.");
397 projectionTol_ < MT::zero(),
398 std::invalid_argument,
399 "Belos::SolutionProjection: projection tolerance must be nonnegative.");
402 reorthogonalizationSteps_ < 1,
403 std::invalid_argument,
404 "Belos::SolutionProjection: reorthogonalization steps must be at least one.");
407 replacementStrategy_ !=
"Restart",
408 std::invalid_argument,
409 "Belos::SolutionProjection: currently only \"Restart\" replacement strategy is implemented.");
412 void validateProjectionInputs(
const MV& x,
const MV& r)
const {
413 TEUCHOS_TEST_FOR_EXCEPTION(
414 MVT::GetNumberVecs(x) != MVT::GetNumberVecs(r),
415 std::invalid_argument,
416 "Belos::SolutionProjection::project(): x and residual/right-hand side must have the same number of vectors.");
418 TEUCHOS_TEST_FOR_EXCEPTION(
419 MVT::GetGlobalLength(x) != MVT::GetGlobalLength(r),
420 std::invalid_argument,
421 "Belos::SolutionProjection::project(): x and residual/right-hand side must have the same global length.");
423 TEUCHOS_TEST_FOR_EXCEPTION(
424 !U_.is_null() && MVT::GetGlobalLength(*U_) != MVT::GetGlobalLength(x),
425 std::invalid_argument,
426 "Belos::SolutionProjection::project(): x has incompatible global length with stored basis.");
428 TEUCHOS_TEST_FOR_EXCEPTION(
429 !C_.is_null() && MVT::GetGlobalLength(*C_) != MVT::GetGlobalLength(r),
430 std::invalid_argument,
431 "Belos::SolutionProjection::project(): residual/right-hand side has incompatible global length with stored basis.");
435 void ensureStorage(
const MV& uPrototype,
const MV& cPrototype) {
437 U_ = MVT::Clone(uPrototype, maxBasisSize_);
439 else if (MVT::GetNumberVecs(*U_) < maxBasisSize_) {
440 Teuchos::RCP<const MV> tmp = U_;
441 U_ = MVT::Clone(*tmp, maxBasisSize_);
446 C_ = MVT::Clone(cPrototype, maxBasisSize_);
448 else if (MVT::GetNumberVecs(*C_) < maxBasisSize_) {
449 Teuchos::RCP<const MV> tmp = C_;
450 C_ = MVT::Clone(*tmp, maxBasisSize_);
455 bool addOnePair(MV& uNew, MV& cNew) {
456 const ScalarType one = SCT::one();
458 std::vector<MagnitudeType> initialNorm(1);
459 MVT::MvNorm(cNew, initialNorm);
461 if (initialNorm[0] == MT::zero()) {
465 if (curBasisSize_ == maxBasisSize_) {
466 if (replacementStrategy_ ==
"Restart") {
472 TEUCHOS_TEST_FOR_EXCEPTION(
474 SolutionProjectionFailure,
475 "Belos::SolutionProjection: unsupported replacement strategy.");
479 for (
int pass = 0; pass < reorthogonalizationSteps_; ++pass) {
480 if (curBasisSize_ == 0) {
484 std::vector<int> ind(curBasisSize_);
485 for (
int i = 0; i < curBasisSize_; ++i) {
489 Teuchos::RCP<const MV> Ucur = MVT::CloneView(*U_, ind);
490 Teuchos::RCP<const MV> Ccur = MVT::CloneView(*C_, ind);
492 Teuchos::RCP<DM> h = DMT::Create(curBasisSize_, 1);
495 MVT::MvTransMv(one, *Ccur, cNew, *h);
498 MVT::MvTimesMatAddMv(-one, *Ccur, *h, one, cNew);
503 MVT::MvTimesMatAddMv(-one, *Ucur, *h, one, uNew);
506 std::vector<MagnitudeType> finalNorm(1);
507 MVT::MvNorm(cNew, finalNorm);
509 if (finalNorm[0] <= projectionTol_ * initialNorm[0]) {
513 const ScalarType scale =
514 static_cast<ScalarType
>(MT::one() / finalNorm[0]);
516 MVT::MvScale(cNew, scale);
517 MVT::MvScale(uNew, scale);
519 std::vector<int> dstInd(1);
520 dstInd[0] = curBasisSize_;
522 MVT::SetBlock(uNew, dstInd, *U_);
523 MVT::SetBlock(cNew, dstInd, *C_);
531 Teuchos::RCP<const OP> A_;
536 std::string replacementStrategy_;
542 int reorthogonalizationSteps_;