16 #ifndef dealii_precondition_h 17 #define dealii_precondition_h 21 #include <deal.II/base/config.h> 23 #include <deal.II/base/memory_space.h> 24 #include <deal.II/base/parallel.h> 25 #include <deal.II/base/smartpointer.h> 26 #include <deal.II/base/template_constraints.h> 27 #include <deal.II/base/thread_management.h> 28 #include <deal.II/base/utilities.h> 30 #include <deal.II/lac/diagonal_matrix.h> 31 #include <deal.II/lac/solver_cg.h> 32 #include <deal.II/lac/vector_memory.h> 34 DEAL_II_NAMESPACE_OPEN
38 template <
typename number>
40 template <
typename number>
46 template <
typename,
typename>
107 template <
typename MatrixType>
115 template <
class VectorType>
117 vmult(VectorType &,
const VectorType &)
const;
123 template <
class VectorType>
125 Tvmult(VectorType &,
const VectorType &)
const;
130 template <
class VectorType>
132 vmult_add(VectorType &,
const VectorType &)
const;
138 template <
class VectorType>
140 Tvmult_add(VectorType &,
const VectorType &)
const;
240 template <
typename MatrixType>
247 template <
class VectorType>
249 vmult(VectorType &,
const VectorType &)
const;
255 template <
class VectorType>
257 Tvmult(VectorType &,
const VectorType &)
const;
261 template <
class VectorType>
263 vmult_add(VectorType &,
const VectorType &)
const;
269 template <
class VectorType>
271 Tvmult_add(VectorType &,
const VectorType &)
const;
361 template <
typename MatrixType = SparseMatrix<
double>,
362 class VectorType = Vector<
double>>
370 const VectorType &)
const;
384 vmult(VectorType &dst,
const VectorType &src)
const;
408 template <
typename MatrixType = SparseMatrix<
double>>
505 template <
typename MatrixType = SparseMatrix<
double>>
518 template <
class VectorType>
520 vmult(VectorType &,
const VectorType &)
const;
526 template <
class VectorType>
528 Tvmult(VectorType &,
const VectorType &)
const;
533 template <
class VectorType>
535 step(VectorType &x,
const VectorType &rhs)
const;
540 template <
class VectorType>
542 Tstep(VectorType &x,
const VectorType &rhs)
const;
593 template <
typename MatrixType = SparseMatrix<
double>>
606 template <
class VectorType>
608 vmult(VectorType &,
const VectorType &)
const;
613 template <
class VectorType>
615 Tvmult(VectorType &,
const VectorType &)
const;
620 template <
class VectorType>
622 step(VectorType &x,
const VectorType &rhs)
const;
627 template <
class VectorType>
629 Tstep(VectorType &x,
const VectorType &rhs)
const;
662 template <
typename MatrixType = SparseMatrix<
double>>
696 template <
class VectorType>
698 vmult(VectorType &,
const VectorType &)
const;
704 template <
class VectorType>
706 Tvmult(VectorType &,
const VectorType &)
const;
712 template <
class VectorType>
714 step(VectorType &x,
const VectorType &rhs)
const;
719 template <
class VectorType>
721 Tstep(VectorType &x,
const VectorType &rhs)
const;
764 template <
typename MatrixType = SparseMatrix<
double>>
845 template <
class VectorType>
847 vmult(VectorType &,
const VectorType &)
const;
852 template <
class VectorType>
854 Tvmult(VectorType &,
const VectorType &)
const;
1003 template <
typename MatrixType = SparseMatrix<
double>,
1004 typename VectorType = Vector<
double>,
1005 typename PreconditionerType = DiagonalMatrix<VectorType>>
1129 vmult(VectorType &dst,
const VectorType &src)
const;
1136 Tvmult(VectorType &dst,
const VectorType &src)
const;
1142 step(VectorType &dst,
const VectorType &src)
const;
1148 Tstep(VectorType &dst,
const VectorType &src)
const;
1245 template <
typename MatrixType>
1255 template <
class VectorType>
1264 template <
class VectorType>
1271 template <
class VectorType>
1280 template <
class VectorType>
1304 const double relaxation)
1305 : relaxation(relaxation)
1314 AdditionalData add_data;
1315 relaxation = add_data.relaxation;
1329 template <
typename MatrixType>
1332 const MatrixType & matrix,
1342 template <
class VectorType>
1347 std::is_same<size_type, typename VectorType::size_type>::value,
1348 "PreconditionRichardson and VectorType must have the same size_type.");
1355 template <
class VectorType>
1360 std::is_same<size_type, typename VectorType::size_type>::value,
1361 "PreconditionRichardson and VectorType must have the same size_type.");
1366 template <
class VectorType>
1371 std::is_same<size_type, typename VectorType::size_type>::value,
1372 "PreconditionRichardson and VectorType must have the same size_type.");
1379 template <
class VectorType>
1384 std::is_same<size_type, typename VectorType::size_type>::value,
1385 "PreconditionRichardson and VectorType must have the same size_type.");
1406 template <
typename MatrixType>
1409 const AdditionalData ¶meters)
1412 relaxation = parameters.relaxation;
1416 template <
typename MatrixType>
1423 template <
typename MatrixType>
1431 template <
typename MatrixType>
1441 template <
typename MatrixType>
1442 template <
class VectorType>
1445 const VectorType &src)
const 1449 typename VectorType::size_type>::value,
1450 "PreconditionJacobi and VectorType must have the same size_type.");
1453 this->A->precondition_Jacobi(dst, src, this->relaxation);
1458 template <
typename MatrixType>
1459 template <
class VectorType>
1462 const VectorType &src)
const 1466 typename VectorType::size_type>::value,
1467 "PreconditionJacobi and VectorType must have the same size_type.");
1470 this->A->precondition_Jacobi(dst, src, this->relaxation);
1475 template <
typename MatrixType>
1476 template <
class VectorType>
1479 const VectorType &src)
const 1483 typename VectorType::size_type>::value,
1484 "PreconditionJacobi and VectorType must have the same size_type.");
1487 this->A->Jacobi_step(dst, src, this->relaxation);
1492 template <
typename MatrixType>
1493 template <
class VectorType>
1496 const VectorType &src)
const 1500 typename VectorType::size_type>::value,
1501 "PreconditionJacobi and VectorType must have the same size_type.");
1510 template <
typename MatrixType>
1511 template <
class VectorType>
1516 typename VectorType::size_type>::value,
1517 "PreconditionSOR and VectorType must have the same size_type.");
1520 this->A->precondition_SOR(dst, src, this->relaxation);
1525 template <
typename MatrixType>
1526 template <
class VectorType>
1529 const VectorType &src)
const 1532 typename VectorType::size_type>::value,
1533 "PreconditionSOR and VectorType must have the same size_type.");
1536 this->A->precondition_TSOR(dst, src, this->relaxation);
1541 template <
typename MatrixType>
1542 template <
class VectorType>
1547 typename VectorType::size_type>::value,
1548 "PreconditionSOR and VectorType must have the same size_type.");
1551 this->A->SOR_step(dst, src, this->relaxation);
1556 template <
typename MatrixType>
1557 template <
class VectorType>
1562 typename VectorType::size_type>::value,
1563 "PreconditionSOR and VectorType must have the same size_type.");
1566 this->A->TSOR_step(dst, src, this->relaxation);
1573 template <
typename MatrixType>
1576 const MatrixType & rA,
1577 const typename BaseClass::AdditionalData ¶meters)
1590 const size_type n = this->A->n();
1591 pos_right_of_diagonal.resize(n, static_cast<std::size_t>(-1));
1592 for (size_type row = 0; row < n; ++row)
1599 it = mat->
begin(row) + 1;
1600 for (; it < mat->
end(row); ++it)
1601 if (it->column() > row)
1603 pos_right_of_diagonal[row] = it - mat->
begin();
1609 template <
typename MatrixType>
1610 template <
class VectorType>
1613 const VectorType &src)
const 1617 typename VectorType::size_type>::value,
1618 "PreconditionSSOR and VectorType must have the same size_type.");
1621 this->A->precondition_SSOR(dst, src, this->relaxation, pos_right_of_diagonal);
1626 template <
typename MatrixType>
1627 template <
class VectorType>
1630 const VectorType &src)
const 1634 typename VectorType::size_type>::value,
1635 "PreconditionSSOR and VectorType must have the same size_type.");
1638 this->A->precondition_SSOR(dst, src, this->relaxation, pos_right_of_diagonal);
1643 template <
typename MatrixType>
1644 template <
class VectorType>
1650 typename VectorType::size_type>::value,
1651 "PreconditionSSOR and VectorType must have the same size_type.");
1654 this->A->SSOR_step(dst, src, this->relaxation);
1659 template <
typename MatrixType>
1660 template <
class VectorType>
1663 const VectorType &src)
const 1667 typename VectorType::size_type>::value,
1668 "PreconditionSSOR and VectorType must have the same size_type.");
1677 template <
typename MatrixType>
1680 const MatrixType & rA,
1681 const std::vector<size_type> & p,
1682 const std::vector<size_type> & ip,
1686 inverse_permutation = &ip;
1691 template <
typename MatrixType>
1694 const AdditionalData &additional_data)
1697 additional_data.permutation,
1698 additional_data.inverse_permutation,
1699 additional_data.parameters);
1703 template <
typename MatrixType>
1704 template <
typename VectorType>
1707 const VectorType &src)
const 1711 typename VectorType::size_type>::value,
1712 "PreconditionPSOR and VectorType must have the same size_type.");
1716 this->A->PSOR(dst, *permutation, *inverse_permutation, this->relaxation);
1721 template <
typename MatrixType>
1722 template <
class VectorType>
1725 const VectorType &src)
const 1729 typename VectorType::size_type>::value,
1730 "PreconditionPSOR and VectorType must have the same size_type.");
1734 this->A->TPSOR(dst, *permutation, *inverse_permutation, this->relaxation);
1737 template <
typename MatrixType>
1739 const std::vector<size_type> &permutation,
1740 const std::vector<size_type> &inverse_permutation,
1742 : permutation(permutation)
1743 , inverse_permutation(inverse_permutation)
1744 , parameters(parameters)
1751 template <
typename MatrixType,
class VectorType>
1753 const MatrixType & M,
1754 const function_ptr method)
1756 , precondition(method)
1761 template <
typename MatrixType,
class VectorType>
1765 const VectorType &src)
const 1767 (
matrix.*precondition)(dst, src);
1772 template <
typename MatrixType>
1774 const double relaxation)
1775 : relaxation(relaxation)
1784 namespace PreconditionChebyshevImplementation
1792 template <
typename VectorType,
typename PreconditionerType>
1794 vector_updates(
const VectorType & rhs,
1795 const PreconditionerType &preconditioner,
1796 const unsigned int iteration_index,
1797 const double factor1,
1798 const double factor2,
1799 VectorType & solution_old,
1800 VectorType & temp_vector1,
1801 VectorType & temp_vector2,
1802 VectorType & solution)
1804 if (iteration_index == 0)
1806 solution.equ(factor2, rhs);
1807 preconditioner.vmult(solution_old, solution);
1809 else if (iteration_index == 1)
1812 temp_vector1.sadd(-1.0, 1.0, rhs);
1813 preconditioner.vmult(solution_old, temp_vector1);
1816 solution_old.sadd(factor2, 1 + factor1, solution);
1821 temp_vector1.sadd(-1.0, 1.0, rhs);
1822 preconditioner.vmult(temp_vector2, temp_vector1);
1825 solution_old.sadd(-factor1, factor2, temp_vector2);
1826 solution_old.add(1 + factor1, solution);
1829 solution.swap(solution_old);
1835 template <
typename Number>
1836 struct VectorUpdater
1838 VectorUpdater(
const Number * rhs,
1839 const Number * matrix_diagonal_inverse,
1840 const unsigned int iteration_index,
1841 const Number factor1,
1842 const Number factor2,
1843 Number * solution_old,
1844 Number * tmp_vector,
1847 , matrix_diagonal_inverse(matrix_diagonal_inverse)
1848 , iteration_index(iteration_index)
1851 , solution_old(solution_old)
1852 , tmp_vector(tmp_vector)
1853 , solution(solution)
1857 apply_to_subrange(
const std::size_t begin,
const std::size_t end)
const 1863 const Number factor1 = this->factor1;
1864 const Number factor1_plus_1 = 1. + this->factor1;
1865 const Number factor2 = this->factor2;
1866 if (iteration_index == 0)
1868 DEAL_II_OPENMP_SIMD_PRAGMA
1869 for (std::size_t i = begin; i < end; ++i)
1870 solution[i] = factor2 * matrix_diagonal_inverse[i] * rhs[i];
1872 else if (iteration_index == 1)
1875 DEAL_II_OPENMP_SIMD_PRAGMA
1876 for (std::size_t i = begin; i < end; ++i)
1880 factor1_plus_1 * solution[i] +
1881 factor2 * matrix_diagonal_inverse[i] * (rhs[i] - tmp_vector[i]);
1887 DEAL_II_OPENMP_SIMD_PRAGMA
1888 for (std::size_t i = begin; i < end; ++i)
1890 factor1_plus_1 * solution[i] - factor1 * solution_old[i] +
1891 factor2 * matrix_diagonal_inverse[i] * (rhs[i] - tmp_vector[i]);
1896 const Number * matrix_diagonal_inverse;
1897 const unsigned int iteration_index;
1898 const Number factor1;
1899 const Number factor2;
1900 mutable Number * solution_old;
1901 mutable Number * tmp_vector;
1902 mutable Number * solution;
1905 template <
typename Number>
1908 VectorUpdatesRange(
const VectorUpdater<Number> &updater,
1909 const std::size_t size)
1912 if (size < internal::VectorImplementation::minimum_parallel_grain_size)
1913 apply_to_subrange(0, size);
1918 internal::VectorImplementation::minimum_parallel_grain_size);
1921 ~VectorUpdatesRange()
override =
default;
1924 apply_to_subrange(
const std::size_t begin,
1925 const std::size_t end)
const override 1927 updater.apply_to_subrange(begin, end);
1930 const VectorUpdater<Number> &updater;
1934 template <
typename Number>
1936 vector_updates(const ::Vector<Number> & rhs,
1938 const unsigned int iteration_index,
1939 const double factor1,
1940 const double factor2,
1941 ::Vector<Number> &solution_old,
1942 ::Vector<Number> &temp_vector1,
1944 ::Vector<Number> &solution)
1946 VectorUpdater<Number> upd(rhs.begin(),
1947 jacobi.get_vector().begin(),
1951 solution_old.begin(),
1952 temp_vector1.begin(),
1954 VectorUpdatesRange<Number>(upd, rhs.size());
1957 if (iteration_index == 0)
1962 else if (iteration_index == 1)
1964 solution.swap(temp_vector1);
1965 solution_old.swap(temp_vector1);
1968 solution.swap(solution_old);
1972 template <
typename Number,
typename MemorySpace>
1978 const unsigned int iteration_index,
1979 const double factor1,
1980 const double factor2,
1986 VectorUpdater<Number> upd(rhs.
begin(),
1987 jacobi.get_vector().begin(),
1991 solution_old.
begin(),
1992 temp_vector1.
begin(),
1994 VectorUpdatesRange<Number>(upd, rhs.
local_size());
1997 if (iteration_index == 0)
2002 else if (iteration_index == 1)
2004 solution.
swap(temp_vector1);
2005 solution_old.
swap(temp_vector1);
2008 solution.
swap(solution_old);
2011 template <
typename MatrixType,
2012 typename VectorType,
2013 typename PreconditionerType>
2015 initialize_preconditioner(
2016 const MatrixType & matrix,
2017 std::shared_ptr<PreconditionerType> &preconditioner,
2021 (void)preconditioner;
2025 template <
typename MatrixType,
typename VectorType>
2027 initialize_preconditioner(
2028 const MatrixType & matrix,
2030 VectorType & diagonal_inverse)
2032 if (preconditioner.get() ==
nullptr || preconditioner->m() !=
matrix.m())
2034 if (preconditioner.get() ==
nullptr)
2038 preconditioner->m() == 0,
2040 "Preconditioner appears to be initialized but not sized correctly"));
2044 preconditioner->reinit(diagonal_inverse);
2046 VectorType empty_vector;
2047 diagonal_inverse.reinit(empty_vector);
2051 if (preconditioner->m() !=
matrix.m())
2053 preconditioner->get_vector().reinit(
matrix.m());
2054 for (
typename VectorType::size_type i = 0; i <
matrix.m(); ++i)
2055 preconditioner->get_vector()(i) = 1. /
matrix.el(i, i);
2060 template <
typename VectorType>
2062 set_initial_guess(VectorType &vector)
2064 vector = 1. / std::sqrt(static_cast<double>(vector.size()));
2065 if (vector.locally_owned_elements().is_element(0))
2069 template <
typename Number>
2071 set_initial_guess(::Vector<Number> &vector)
2077 for (
unsigned int i = 0; i < vector.size(); ++i)
2080 const Number mean_value = vector.mean_value();
2081 vector.add(-mean_value);
2084 template <
typename Number,
typename MemorySpace>
2098 for (
unsigned int i = 0; i < vector.
local_size(); ++i)
2101 const Number mean_value = vector.
mean_value();
2102 vector.
add(-mean_value);
2105 struct EigenvalueTracker
2114 std::vector<double> values;
2123 template <
typename MatrixType,
class VectorType,
typename PreconditionerType>
2126 const double smoothing_range,
2127 const bool nonzero_starting,
2128 const unsigned int eig_cg_n_iterations,
2129 const double eig_cg_residual,
2130 const double max_eigenvalue)
2132 , smoothing_range(smoothing_range)
2133 , nonzero_starting(nonzero_starting)
2134 , eig_cg_n_iterations(eig_cg_n_iterations)
2135 , eig_cg_residual(eig_cg_residual)
2136 , max_eigenvalue(max_eigenvalue)
2141 template <
typename MatrixType,
typename VectorType,
typename PreconditionerType>
2146 , eigenvalues_are_initialized(false)
2149 std::is_same<size_type, typename VectorType::size_type>::value,
2150 "PreconditionChebyshev and VectorType must have the same size_type.");
2157 template <
typename MatrixType,
typename VectorType,
typename PreconditionerType>
2160 const MatrixType & matrix,
2161 const AdditionalData &additional_data)
2164 data = additional_data;
2166 ExcMessage(
"The degree of the Chebyshev method must be positive."));
2167 internal::PreconditionChebyshevImplementation::initialize_preconditioner(
2168 matrix, data.preconditioner, data.matrix_diagonal_inverse);
2169 eigenvalues_are_initialized =
false;
2174 template <
typename MatrixType,
typename VectorType,
typename PreconditionerType>
2178 eigenvalues_are_initialized =
false;
2179 theta = delta = 1.0;
2180 matrix_ptr =
nullptr;
2182 VectorType empty_vector;
2183 data.matrix_diagonal_inverse.reinit(empty_vector);
2184 solution_old.
reinit(empty_vector);
2185 temp_vector1.
reinit(empty_vector);
2186 temp_vector2.reinit(empty_vector);
2188 data.preconditioner.reset();
2193 template <
typename MatrixType,
typename VectorType,
typename PreconditionerType>
2201 solution_old.
reinit(src);
2202 temp_vector1.
reinit(src,
true);
2207 double max_eigenvalue, min_eigenvalue;
2208 if (data.eig_cg_n_iterations > 0)
2210 Assert(data.eig_cg_n_iterations > 2,
2212 "Need to set at least two iterations to find eigenvalues."));
2216 data.eig_cg_n_iterations,
2218 std::numeric_limits<typename VectorType::value_type>::epsilon()),
2223 internal::PreconditionChebyshevImplementation::EigenvalueTracker
2226 solver.connect_eigenvalues_slot(std::bind(
2227 &internal::PreconditionChebyshevImplementation::EigenvalueTracker::slot,
2228 &eigenvalue_tracker,
2229 std::placeholders::_1));
2233 internal::PreconditionChebyshevImplementation::set_initial_guess(
2238 solver.solve(*matrix_ptr,
2241 *data.preconditioner);
2247 if (eigenvalue_tracker.values.empty())
2248 min_eigenvalue = max_eigenvalue = 1;
2251 min_eigenvalue = eigenvalue_tracker.values.front();
2255 max_eigenvalue = 1.2 * eigenvalue_tracker.values.back();
2260 max_eigenvalue = data.max_eigenvalue;
2261 min_eigenvalue = data.max_eigenvalue / data.smoothing_range;
2264 const double alpha = (data.smoothing_range > 1. ?
2265 max_eigenvalue / data.smoothing_range :
2266 std::min(0.9 * max_eigenvalue, min_eigenvalue));
2275 const double actual_range = max_eigenvalue / alpha;
2276 const double sigma = (1. - std::sqrt(1. / actual_range)) /
2277 (1. + std::sqrt(1. / actual_range));
2278 const double eps = data.smoothing_range;
2283 1 + static_cast<unsigned int>(
2284 std::log(1. / eps + std::sqrt(1. / eps / eps - 1)) /
2285 std::log(1. / sigma));
2290 ->delta = (max_eigenvalue - alpha) * 0.5;
2293 ->theta = (max_eigenvalue + alpha) * 0.5;
2297 using NumberType =
typename VectorType::value_type;
2300 (std::is_same<VectorType, ::Vector<NumberType>>::value ==
false &&
2301 ((std::is_same<VectorType,
2303 Vector<NumberType, MemorySpace::Host>>::value ==
2305 (std::is_same<VectorType,
2306 LinearAlgebra::distributed::
2307 Vector<NumberType, MemorySpace::CUDA>>::value ==
2309 temp_vector2.reinit(src,
true);
2312 VectorType empty_vector;
2313 temp_vector2.reinit(empty_vector);
2318 ->eigenvalues_are_initialized =
true;
2323 template <
typename MatrixType,
typename VectorType,
typename PreconditionerType>
2326 VectorType & solution,
2327 const VectorType &rhs)
const 2329 std::lock_guard<std::mutex> lock(mutex);
2330 if (eigenvalues_are_initialized ==
false)
2331 estimate_eigenvalues(rhs);
2333 internal::PreconditionChebyshevImplementation::vector_updates(
2335 *data.preconditioner,
2346 if (data.degree < 2 || std::abs(delta) < 1e-40)
2349 double rhok = delta / theta, sigma = theta / delta;
2350 for (
unsigned int k = 0; k < data.degree - 1; ++k)
2352 matrix_ptr->vmult(temp_vector1, solution);
2353 const double rhokp = 1. / (2. * sigma - rhok);
2354 const double factor1 = rhokp * rhok, factor2 = 2. * rhokp / delta;
2356 internal::PreconditionChebyshevImplementation::vector_updates(
2358 *data.preconditioner,
2371 template <
typename MatrixType,
typename VectorType,
typename PreconditionerType>
2374 VectorType & solution,
2375 const VectorType &rhs)
const 2377 std::lock_guard<std::mutex> lock(mutex);
2378 if (eigenvalues_are_initialized ==
false)
2379 estimate_eigenvalues(rhs);
2381 internal::PreconditionChebyshevImplementation::vector_updates(
2383 *data.preconditioner,
2392 if (data.degree < 2 || std::abs(delta) < 1e-40)
2395 double rhok = delta / theta, sigma = theta / delta;
2396 for (
unsigned int k = 0; k < data.degree - 1; ++k)
2398 matrix_ptr->Tvmult(temp_vector1, solution);
2399 const double rhokp = 1. / (2. * sigma - rhok);
2400 const double factor1 = rhokp * rhok, factor2 = 2. * rhokp / delta;
2402 internal::PreconditionChebyshevImplementation::vector_updates(
2404 *data.preconditioner,
2417 template <
typename MatrixType,
typename VectorType,
typename PreconditionerType>
2420 VectorType & solution,
2421 const VectorType &rhs)
const 2423 std::lock_guard<std::mutex> lock(mutex);
2424 if (eigenvalues_are_initialized ==
false)
2425 estimate_eigenvalues(rhs);
2427 matrix_ptr->vmult(temp_vector1, solution);
2428 internal::PreconditionChebyshevImplementation::vector_updates(
2430 *data.preconditioner,
2439 if (data.degree < 2 || std::abs(delta) < 1e-40)
2442 double rhok = delta / theta, sigma = theta / delta;
2443 for (
unsigned int k = 0; k < data.degree - 1; ++k)
2445 matrix_ptr->vmult(temp_vector1, solution);
2446 const double rhokp = 1. / (2. * sigma - rhok);
2447 const double factor1 = rhokp * rhok, factor2 = 2. * rhokp / delta;
2449 internal::PreconditionChebyshevImplementation::vector_updates(
2451 *data.preconditioner,
2464 template <
typename MatrixType,
typename VectorType,
typename PreconditionerType>
2467 VectorType & solution,
2468 const VectorType &rhs)
const 2470 std::lock_guard<std::mutex> lock(mutex);
2471 if (eigenvalues_are_initialized ==
false)
2472 estimate_eigenvalues(rhs);
2474 matrix_ptr->Tvmult(temp_vector1, solution);
2475 internal::PreconditionChebyshevImplementation::vector_updates(
2477 *data.preconditioner,
2486 if (data.degree < 2 || std::abs(delta) < 1e-40)
2489 double rhok = delta / theta, sigma = theta / delta;
2490 for (
unsigned int k = 0; k < data.degree - 1; ++k)
2492 matrix_ptr->Tvmult(temp_vector1, solution);
2493 const double rhokp = 1. / (2. * sigma - rhok);
2494 const double factor1 = rhokp * rhok, factor2 = 2. * rhokp / delta;
2496 internal::PreconditionChebyshevImplementation::vector_updates(
2498 *data.preconditioner,
2511 template <
typename MatrixType,
typename VectorType,
typename PreconditionerType>
2514 PreconditionerType>::size_type
2518 return matrix_ptr->m();
2523 template <
typename MatrixType,
typename VectorType,
typename PreconditionerType>
2526 PreconditionerType>::size_type
2530 return matrix_ptr->n();
2535 DEAL_II_NAMESPACE_CLOSE
void Tvmult(VectorType &, const VectorType &) const
size_type local_size() const
static const unsigned int invalid_unsigned_int
types::global_dof_index size_type
void initialize(const MatrixType &A, const typename BaseClass::AdditionalData ¶meters=typename BaseClass::AdditionalData())
const_iterator end() const
Contents is actually a matrix.
size_type nth_index_in_set(const unsigned int local_index) const
void Tstep(VectorType &x, const VectorType &rhs) const
std::array< Number, 1 > eigenvalues(const SymmetricTensor< 2, 1, Number > &T)
void vmult(VectorType &dst, const VectorType &src) const
void Tvmult_add(VectorType &, const VectorType &) const
PreconditionRelaxation< MatrixType >::AdditionalData parameters
void vmult(VectorType &, const VectorType &) const
const MatrixType & matrix
void reinit(const size_type size, const bool omit_zeroing_entries=false)
AdditionalData(const double relaxation=1.)
void(MatrixType::*)(VectorType &, const VectorType &) const function_ptr
static ::ExceptionBase & ExcNotInitialized()
void initialize(const MatrixType &matrix, const AdditionalData &additional_data=AdditionalData())
std::shared_ptr< PreconditionerType > preconditioner
#define AssertThrow(cond, exc)
AdditionalData(const double relaxation=1.)
const std::vector< size_type > * permutation
LinearAlgebra::distributed::Vector< Number > Vector
const function_ptr precondition
void vmult(VectorType &, const VectorType &) const
void initialize(const AdditionalData ¶meters)
Number local_element(const size_type local_index) const
void Tvmult(VectorType &, const VectorType &) const
static ::ExceptionBase & ExcMessage(std::string arg1)
typename MatrixType::size_type size_type
void Tvmult(VectorType &dst, const VectorType &src) const
void vmult(VectorType &, const VectorType &) const
const std::vector< size_type > & inverse_permutation
#define Assert(cond, exc)
typename PreconditionRelaxation< MatrixType >::AdditionalData AdditionalData
bool eigenvalues_are_initialized
void step(VectorType &x, const VectorType &rhs) const
typename MatrixType::size_type size_type
AdditionalData(const unsigned int degree=1, const double smoothing_range=0., const bool nonzero_starting=false, const unsigned int eig_cg_n_iterations=8, const double eig_cg_residual=1e-2, const double max_eigenvalue=1)
void vmult_add(VectorType &, const VectorType &) const
void Tvmult(VectorType &, const VectorType &) const
void initialize(const MatrixType &A, const AdditionalData ¶meters=AdditionalData())
void Tvmult(VectorType &, const VectorType &) const
void estimate_eigenvalues(const VectorType &src) const
void Tstep(VectorType &x, const VectorType &rhs) const
void vmult(VectorType &, const VectorType &) const
void Tstep(VectorType &x, const VectorType &rhs) const
void vmult(VectorType &dst, const VectorType &src) const
AdditionalData(const std::vector< size_type > &permutation, const std::vector< size_type > &inverse_permutation, const typename PreconditionRelaxation< MatrixType >::AdditionalData ¶meters=typename PreconditionRelaxation< MatrixType >::AdditionalData())
VectorType matrix_diagonal_inverse
void Tvmult_add(VectorType &, const VectorType &) const
void Tvmult(VectorType &, const VectorType &) const
types::global_dof_index size_type
void vmult(VectorType &, const VectorType &) const
unsigned int global_dof_index
virtual ::IndexSet locally_owned_elements() const override
SmartPointer< const MatrixType, PreconditionRelaxation< MatrixType > > A
void Tvmult(VectorType &, const VectorType &) const
void step(VectorType &x, const VectorType &rhs) const
void initialize(const MatrixType &matrix, const AdditionalData &additional_data=AdditionalData())
void swap(Vector< Number, MemorySpace > &v)
typename MatrixType::size_type size_type
const std::vector< size_type > * inverse_permutation
void Tstep(VectorType &dst, const VectorType &src) const
void step(VectorType &dst, const VectorType &src) const
void step(VectorType &x, const VectorType &rhs) const
virtual void add(const Number a) override
types::global_dof_index size_type
unsigned int eig_cg_n_iterations
const_iterator begin() const
typename PreconditionRelaxation< MatrixType >::AdditionalData AdditionalData
void vmult(VectorType &, const VectorType &) const
const std::vector< size_type > & permutation
PreconditionUseMatrix(const MatrixType &M, const function_ptr method)
typename PreconditionRelaxation< MatrixType >::AdditionalData AdditionalData
virtual Number mean_value() const override
void vmult_add(VectorType &, const VectorType &) const
std::vector< std::size_t > pos_right_of_diagonal
SmartPointer< const MatrixType, PreconditionChebyshev< MatrixType, VectorType, PreconditionerType > > matrix_ptr
std::array< std::pair< Number, Tensor< 1, dim, Number > >, dim > jacobi(::SymmetricTensor< 2, dim, Number > A)
static ::ExceptionBase & ExcInternalError()
void initialize(const MatrixType &A, const std::vector< size_type > &permutation, const std::vector< size_type > &inverse_permutation, const typename PreconditionRelaxation< MatrixType >::AdditionalData ¶meters=typename PreconditionRelaxation< MatrixType >::AdditionalData())