--- /dev/null
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2023 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE.md at
+// the top level directory of deal.II.
+//
+// ---------------------------------------------------------------------
+
+#ifndef dealii_lac_orthogonalization_h
+#define dealii_lac_orthogonalization_h
+
+
+#include <deal.II/base/config.h>
+
+DEAL_II_NAMESPACE_OPEN
+
+namespace LinearAlgebra
+{
+ /**
+ * Supported orthogonalization strategies within SolverGMRES and
+ * SolverFGMRES.
+ */
+ enum class OrthogonalizationStrategy
+ {
+ /**
+ * Use modified Gram-Schmidt algorithm.
+ */
+ modified_gram_schmidt,
+ /**
+ * Use classical Gram-Schmidt algorithm. Since this approach works on
+ * multi-vectors with a single global reduction (of multiple elements), it
+ * is more efficient than the modified Gram-Schmidt algorithm. However, it
+ * is less stable in terms of roundoff error propagation, requiring
+ * additional re-orthogonalization steps more frequently.
+ */
+ classical_gram_schmidt
+ };
+} // namespace LinearAlgebra
+
+
+DEAL_II_NAMESPACE_CLOSE
+
+#endif
#include <deal.II/lac/full_matrix.h>
#include <deal.II/lac/householder.h>
#include <deal.II/lac/lapack_full_matrix.h>
+#include <deal.II/lac/orthogonalization.h>
#include <deal.II/lac/solver.h>
#include <deal.II/lac/solver_control.h>
#include <deal.II/lac/vector.h>
*/
struct AdditionalData
{
- enum class OrthogonalizationStrategy
- {
- /**
- * Use modified Gram-Schmidt algorithm.
- */
- modified_gram_schmidt,
- /**
- * Use classical Gram-Schmidt algorithm. Since this approach works on
- * multi-vectors and performs a global reduction only once, it is
- * more efficient than the modified Gram-Schmidt algorithm.
- * However, it might be numerically unstable.
- */
- classical_gram_schmidt
- };
-
/**
* Constructor. By default, set the number of temporary vectors to 30,
* i.e. do a restart every 28 iterations. Also set preconditioning from
* reduced functionality to track information is disabled by default.
*/
explicit AdditionalData(
- const unsigned int max_n_tmp_vectors = 30,
- const bool right_preconditioning = false,
- const bool use_default_residual = true,
- const bool force_re_orthogonalization = false,
- const bool batched_mode = false,
- const OrthogonalizationStrategy orthogonalization_strategy =
- OrthogonalizationStrategy::modified_gram_schmidt);
+ const unsigned int max_n_tmp_vectors = 30,
+ const bool right_preconditioning = false,
+ const bool use_default_residual = true,
+ const bool force_re_orthogonalization = false,
+ const bool batched_mode = false,
+ const LinearAlgebra::OrthogonalizationStrategy
+ orthogonalization_strategy =
+ LinearAlgebra::OrthogonalizationStrategy::modified_gram_schmidt);
/**
* Maximum number of temporary vectors. This parameter controls the size
/**
* Strategy to orthogonalize vectors.
*/
- OrthogonalizationStrategy orthogonalization_strategy;
+ LinearAlgebra::OrthogonalizationStrategy orthogonalization_strategy;
};
/**
/**
* Constructor. By default, set the maximum basis size to 30.
*/
- explicit AdditionalData(const unsigned int max_basis_size = 30)
+ explicit AdditionalData(
+ const unsigned int max_basis_size = 30,
+ const LinearAlgebra::OrthogonalizationStrategy
+ orthogonalization_strategy =
+ LinearAlgebra::OrthogonalizationStrategy::modified_gram_schmidt)
: max_basis_size(max_basis_size)
+ , orthogonalization_strategy(orthogonalization_strategy)
{}
/**
* Maximum basis size.
*/
unsigned int max_basis_size;
+
+ /**
+ * Strategy to orthogonalize vectors.
+ */
+ LinearAlgebra::OrthogonalizationStrategy orthogonalization_strategy;
};
/**
template <class VectorType>
inline SolverGMRES<VectorType>::AdditionalData::AdditionalData(
- const unsigned int max_n_tmp_vectors,
- const bool right_preconditioning,
- const bool use_default_residual,
- const bool force_re_orthogonalization,
- const bool batched_mode,
- const OrthogonalizationStrategy orthogonalization_strategy)
+ const unsigned int max_n_tmp_vectors,
+ const bool right_preconditioning,
+ const bool use_default_residual,
+ const bool force_re_orthogonalization,
+ const bool batched_mode,
+ const LinearAlgebra::OrthogonalizationStrategy orthogonalization_strategy)
: max_n_tmp_vectors(max_n_tmp_vectors)
, right_preconditioning(right_preconditioning)
, use_default_residual(use_default_residual)
template <class VectorType>
inline double
iterated_gram_schmidt(
- const typename SolverGMRES<VectorType>::AdditionalData::
- OrthogonalizationStrategy orthogonalization_strategy,
+ const LinearAlgebra::OrthogonalizationStrategy orthogonalization_strategy,
const internal::SolverGMRESImplementation::TmpVectors<VectorType>
& orthogonal_vectors,
const unsigned int dim,
double norm_vv = 0.0;
if (orthogonalization_strategy ==
- SolverGMRES<VectorType>::AdditionalData::
- OrthogonalizationStrategy::modified_gram_schmidt)
+ LinearAlgebra::OrthogonalizationStrategy::modified_gram_schmidt)
{
double htmp = vv * orthogonal_vectors[0];
h(0) += htmp;
vv.add_and_dot(-htmp, orthogonal_vectors[dim - 1], vv));
}
else if (orthogonalization_strategy ==
- SolverGMRES<VectorType>::AdditionalData::
- OrthogonalizationStrategy::classical_gram_schmidt)
+ LinearAlgebra::OrthogonalizationStrategy::
+ classical_gram_schmidt)
{
Tvmult_add(dim, vv, orthogonal_vectors, h);
norm_vv = substract_and_norm(dim, orthogonal_vectors, h, vv);
bool re_orthogonalize = false;
const double s =
internal::SolverGMRESImplementation::iterated_gram_schmidt<
- VectorType>(SolverGMRES<VectorType>::AdditionalData::
- OrthogonalizationStrategy::modified_gram_schmidt,
+ VectorType>(additional_data.orthogonalization_strategy,
v,
j + 1,
0,
// ---------------------------------------------------------------------
// Check the path of SolverGMRES with distributed vectors and
-// OrthogonalizationStrategy::classical_gram_schmidt.
+// LinearAlgebra::OrthogonalizationStrategy::classical_gram_schmidt.
#include <deal.II/lac/diagonal_matrix.h>
SolverGMRES<LinearAlgebra::distributed::Vector<double>>::AdditionalData
data3(8);
data3.orthogonalization_strategy =
- SolverGMRES<LinearAlgebra::distributed::Vector<double>>::AdditionalData::
- OrthogonalizationStrategy::classical_gram_schmidt;
+ LinearAlgebra::OrthogonalizationStrategy::classical_gram_schmidt;
SolverGMRES<LinearAlgebra::distributed::Vector<double>> solver(control,
data3);
solver.connect(&monitor_norm);
SolverGMRES<LinearAlgebra::distributed::BlockVector<double>>::AdditionalData
data3(8);
data3.orthogonalization_strategy =
- SolverGMRES<LinearAlgebra::distributed::BlockVector<double>>::
- AdditionalData::OrthogonalizationStrategy::classical_gram_schmidt;
+ LinearAlgebra::OrthogonalizationStrategy::classical_gram_schmidt;
SolverGMRES<LinearAlgebra::distributed::BlockVector<double>> solver(control,
data3);
solver.connect(&monitor_norm_block);