15#ifndef dealii_solver_cg_h
16#define dealii_solver_cg_h
42 template <
typename,
typename>
194template <
typename VectorType = Vector<
double>>
254 template <
typename MatrixType,
typename PreconditionerType>
258 void solve(const MatrixType &A,
261 const PreconditionerType &preconditioner);
269 boost::signals2::connection
270 connect_coefficients_slot(
271 const
std::function<
void(typename VectorType::value_type,
272 typename VectorType::value_type)> &slot);
280 boost::signals2::connection
281 connect_condition_number_slot(const
std::function<
void(
double)> &slot,
282 const
bool every_iteration = false);
290 boost::signals2::connection
291 connect_eigenvalues_slot(
292 const
std::function<
void(const
std::vector<
double> &)> &slot,
293 const
bool every_iteration = false);
302 print_vectors(const
unsigned int step,
305 const VectorType &d) const;
313 compute_eigs_and_cond(
314 const
std::vector<typename VectorType::value_type> &diagonal,
315 const
std::vector<typename VectorType::value_type> &offdiagonal,
316 const
boost::signals2::signal<
void(const
std::vector<
double> &)>
318 const
boost::signals2::signal<
void(
double)> &cond_signal);
328 boost::signals2::signal<
void(typename VectorType::value_type,
329 typename VectorType::value_type)>
336 boost::signals2::signal<
void(
double)> condition_number_signal;
342 boost::signals2::signal<
void(
double)> all_condition_numbers_signal;
348 boost::signals2::signal<
void(const
std::vector<
double> &)> eigenvalues_signal;
354 boost::signals2::signal<
void(const
std::vector<
double> &)>
355 all_eigenvalues_signal;
365 bool determine_beta_by_flexible_formula;
395template <typename VectorType =
Vector<
double>>
463template <
typename VectorType>
466 const bool use_default_residual)
467 : use_default_residual(use_default_residual)
470template <
typename VectorType>
474 const AdditionalData &
data)
476 , additional_data(
data)
477 , determine_beta_by_flexible_formula(false)
482template <
typename VectorType>
486 , additional_data(
data)
487 , determine_beta_by_flexible_formula(false)
492template <
typename VectorType>
497 const VectorType &)
const
502template <
typename VectorType>
505 const std::vector<typename VectorType::value_type> &diagonal,
506 const std::vector<typename VectorType::value_type> &offdiagonal,
507 const boost::signals2::signal<
void(
const std::vector<double> &)>
509 const boost::signals2::signal<
void(
double)> &cond_signal)
512 if (!cond_signal.empty() || !eigenvalues_signal.empty())
516 for (size_type i = 0; i <
diagonal.size(); ++i)
520 T(i, i + 1) = offdiagonal[i];
522 T.compute_eigenvalues();
526 auto condition_number = T.eigenvalue(T.n() - 1) / T.eigenvalue(0);
529 cond_signal(
std::abs(condition_number));
533 if (!eigenvalues_signal.empty())
536 for (
unsigned int j = 0; j < T.n(); ++j)
562 typename PreconditionerType>
563 struct IterationWorkerBase
565 using Number =
typename VectorType::value_type;
568 const PreconditionerType &preconditioner;
591 Number r_dot_preconditioner_dot_r;
594 double residual_norm;
595 Number previous_alpha;
596 const bool use_default_residual;
599 IterationWorkerBase(
const MatrixType &A,
600 const PreconditionerType &preconditioner,
605 const bool &use_default_residual)
607 , preconditioner(preconditioner)
615 , explicit_r_pointer(memory)
620 , explicit_r(*explicit_r_pointer)
621 , r_dot_preconditioner_dot_r(Number())
625 , previous_alpha(Number())
626 , use_default_residual(use_default_residual)
639 if (!use_default_residual)
640 explicit_r.reinit(x,
true);
652 residual_norm = r.l2_norm();
662 typename PreconditionerType,
664 struct IterationWorker
665 :
public IterationWorkerBase<VectorType, MatrixType, PreconditionerType>
668 IterationWorkerBase<VectorType, MatrixType, PreconditionerType>;
671 IterationWorker(
const MatrixType &A,
672 const PreconditionerType &preconditioner,
677 const bool &use_default_residual)
684 use_default_residual)
688 using BaseClass::alpha;
690 using BaseClass::beta;
691 using BaseClass::explicit_r;
693 using BaseClass::preconditioner;
695 using BaseClass::r_dot_preconditioner_dot_r;
696 using BaseClass::residual_norm;
697 using BaseClass::use_default_residual;
703 do_iteration(
const unsigned int iteration_index)
705 using Number =
typename VectorType::value_type;
707 const Number previous_r_dot_preconditioner_dot_r =
708 r_dot_preconditioner_dot_r;
710 if (std::is_same_v<PreconditionerType, PreconditionIdentity> ==
false)
712 preconditioner.vmult(v, r);
713 r_dot_preconditioner_dot_r = r * v;
716 r_dot_preconditioner_dot_r = residual_norm * residual_norm;
719 std::is_same_v<PreconditionerType, PreconditionIdentity> ? r : v;
721 if (iteration_index > 1)
726 r_dot_preconditioner_dot_r / previous_r_dot_preconditioner_dot_r;
728 beta -= (r * z) / previous_r_dot_preconditioner_dot_r;
729 p.sadd(beta, 1., direction);
732 p.equ(1., direction);
739 const Number p_dot_A_dot_p = p * v;
742 this->previous_alpha = alpha;
743 alpha = r_dot_preconditioner_dot_r / p_dot_A_dot_p;
748 if (use_default_residual)
759 A.vmult(explicit_r, x);
760 explicit_r.add(-1, b);
761 residual_norm = explicit_r.l2_norm();
766 finalize_after_convergence(
const unsigned int)
778 template <
typename MatrixType,
typename VectorType>
779 using vmult_functions_t =
decltype(std::declval<const MatrixType>().vmult(
780 std::declval<VectorType &>(),
781 std::declval<const VectorType &>(),
783 const std::function<
void(
const unsigned int,
const unsigned int)> &>(),
784 std::declval<
const std::function<
void(
const unsigned int,
785 const unsigned int)> &>()));
787 template <
typename MatrixType,
typename VectorType>
788 constexpr bool has_vmult_functions =
789 is_supported_operation<vmult_functions_t, MatrixType, VectorType>;
794 template <
typename PreconditionerType>
795 using apply_to_subrange_t =
796 decltype(std::declval<const PreconditionerType>()
797 .apply_to_subrange(0U, 0U,
nullptr,
nullptr));
799 template <
typename PreconditionerType>
800 constexpr bool has_apply_to_subrange =
801 is_supported_operation<apply_to_subrange_t, PreconditionerType>;
806 template <
typename PreconditionerType>
808 decltype(std::declval<const PreconditionerType>().apply(0U, 0.0));
810 template <
typename PreconditionerType>
811 constexpr bool has_apply =
812 is_supported_operation<apply_t, PreconditionerType>;
820 typename PreconditionerType>
821 struct IterationWorker<
825 std::enable_if_t<has_vmult_functions<MatrixType, VectorType> &&
826 (has_apply_to_subrange<PreconditionerType> ||
827 has_apply<PreconditionerType>)&&std::
828 is_same_v<VectorType,
829 LinearAlgebra::distributed::Vector<
830 typename VectorType::value_type,
833 :
public IterationWorkerBase<VectorType, MatrixType, PreconditionerType>
835 using Number =
typename VectorType::value_type;
837 Number next_r_dot_preconditioner_dot_r;
838 Number previous_beta;
840 IterationWorker(
const MatrixType &A,
841 const PreconditionerType &preconditioner,
846 const bool &use_default_residual)
854 use_default_residual)
855 , next_r_dot_preconditioner_dot_r(0.)
862 do_iteration(
const unsigned int iteration_index)
864 if (iteration_index > 1)
866 previous_beta = this->beta;
867 this->beta = next_r_dot_preconditioner_dot_r /
868 this->r_dot_preconditioner_dot_r;
871 std::array<VectorizedArray<Number>, 7> vectorized_sums = {};
876 [&](
const unsigned int begin,
const unsigned int end) {
877 operation_before_loop(iteration_index, begin, end);
879 [&](
const unsigned int begin,
const unsigned int end) {
880 operation_after_loop(begin, end, vectorized_sums);
883 std::array<Number, 7> scalar_sums;
884 for (
unsigned int i = 0; i < 7; ++i)
885 scalar_sums[i] = vectorized_sums[i][0];
886 for (
unsigned int l = 1; l < VectorizedArray<Number>::size(); ++
l)
887 for (
unsigned int i = 0; i < 7; ++i)
888 scalar_sums[i] += vectorized_sums[i][l];
892 this->r.get_mpi_communicator(),
895 this->r_dot_preconditioner_dot_r = scalar_sums[6];
897 const Number p_dot_A_dot_p = scalar_sums[0];
900 this->previous_alpha = this->alpha;
901 this->alpha = this->r_dot_preconditioner_dot_r / p_dot_A_dot_p;
907 this->alpha * (-2. * scalar_sums[2] + this->alpha * scalar_sums[1])));
909 next_r_dot_preconditioner_dot_r =
std::abs(
910 this->r_dot_preconditioner_dot_r +
911 this->alpha * (-2. * scalar_sums[4] + this->alpha * scalar_sums[5]));
916 template <
typename U =
void>
917 std::enable_if_t<has_apply<PreconditionerType>, U>
918 operation_before_loop(
const unsigned int iteration_index,
919 const unsigned int start_range,
920 const unsigned int end_range)
const
922 Number *x = this->x.begin();
923 Number *r = this->r.begin();
924 Number *p = this->p.begin();
925 Number *v = this->v.begin();
926 const Number alpha = this->alpha;
927 const Number beta = this->beta;
929 const unsigned int end_regular =
930 start_range + (end_range - start_range) / n_lanes * n_lanes;
931 if (iteration_index == 1)
936 for (
unsigned int j = start_range; j < end_regular; j += n_lanes)
941 for (
unsigned int l = 0;
l < n_lanes; ++
l)
942 pj[l] = this->preconditioner.apply(j + l, rj[l]);
947 for (
unsigned int j = end_regular; j < end_range; ++j)
949 p[j] = this->preconditioner.apply(j, r[j]);
953 else if (iteration_index % 2 == 0 && beta != Number())
955 for (
unsigned int j = start_range; j < end_regular; j += n_lanes)
963 for (
unsigned int l = 0;
l < n_lanes; ++
l)
964 prec_rj[l] = this->preconditioner.apply(j + l, rj[l]);
966 pj = beta * pj + prec_rj;
971 for (
unsigned int j = end_regular; j < end_range; ++j)
973 r[j] -= alpha * v[j];
974 p[j] = beta * p[j] + this->preconditioner.apply(j, r[j]);
978 else if (iteration_index % 2 == 0 && beta == Number())
983 for (
unsigned int j = start_range; j < end_regular; j += n_lanes)
995 for (
unsigned int l = 0;
l < n_lanes; ++
l)
996 prec_rj[l] = this->preconditioner.apply(j + l, rj[l]);
997 prec_rj.
store(p + j);
1001 for (
unsigned int j = end_regular; j < end_range; ++j)
1003 r[j] -= alpha * v[j];
1004 x[j] += alpha * p[j];
1005 p[j] = this->preconditioner.apply(j, r[j]);
1011 const Number alpha_plus_previous_alpha_over_beta =
1012 alpha + this->previous_alpha / this->previous_beta;
1013 const Number previous_alpha_over_beta =
1014 this->previous_alpha / this->previous_beta;
1015 for (
unsigned int j = start_range; j < end_regular; j += n_lanes)
1020 xj += alpha_plus_previous_alpha_over_beta * pj;
1024 for (
unsigned int l = 0;
l < n_lanes; ++
l)
1026 prec_rj[
l] = this->preconditioner.apply(j + l, rj[l]);
1027 prec_vj[
l] = this->preconditioner.apply(j + l, vj[l]);
1029 xj -= previous_alpha_over_beta * prec_rj;
1033 prec_rj -= alpha * prec_vj;
1034 pj = beta * pj + prec_rj;
1039 for (
unsigned int j = end_regular; j < end_range; ++j)
1041 x[j] += alpha_plus_previous_alpha_over_beta * p[j];
1042 x[j] -= previous_alpha_over_beta *
1043 this->preconditioner.apply(j, r[j]);
1044 r[j] -= alpha * v[j];
1045 p[j] = beta * p[j] + this->preconditioner.apply(j, r[j]);
1053 template <
typename U =
void>
1054 std::enable_if_t<has_apply<PreconditionerType>, U>
1055 operation_after_loop(
1056 const unsigned int start_range,
1057 const unsigned int end_range,
1060 const Number *r = this->r.begin();
1061 const Number *p = this->p.begin();
1062 const Number *v = this->v.begin();
1063 std::array<VectorizedArray<Number>, 7> my_sums = {};
1065 const unsigned int end_regular =
1066 start_range + (end_range - start_range) / n_lanes * n_lanes;
1067 for (
unsigned int j = start_range; j < end_regular; j += n_lanes)
1074 for (
unsigned int l = 0;
l < n_lanes; ++
l)
1076 prec_vj[
l] = this->preconditioner.apply(j + l, vj[l]);
1077 prec_rj[
l] = this->preconditioner.apply(j + l, rj[l]);
1079 my_sums[0] += pj * vj;
1080 my_sums[1] += vj * vj;
1081 my_sums[2] += rj * vj;
1082 my_sums[3] += rj * rj;
1083 my_sums[4] += rj * prec_vj;
1084 my_sums[5] += vj * prec_vj;
1085 my_sums[6] += rj * prec_rj;
1087 for (
unsigned int j = end_regular; j < end_range; ++j)
1089 const Number prec_v = this->preconditioner.apply(j, v[j]);
1090 const Number prec_r = this->preconditioner.apply(j, r[j]);
1091 my_sums[0][0] += p[j] * v[j];
1092 my_sums[1][0] += v[j] * v[j];
1093 my_sums[2][0] += r[j] * v[j];
1094 my_sums[3][0] += r[j] * r[j];
1095 my_sums[4][0] += r[j] * prec_v;
1096 my_sums[5][0] += v[j] * prec_v;
1097 my_sums[6][0] += r[j] * prec_r;
1099 for (
unsigned int i = 0; i < vectorized_sums.size(); ++i)
1100 vectorized_sums[i] += my_sums[i];
1105 template <
typename U =
void>
1106 std::enable_if_t<has_apply<PreconditionerType>, U>
1107 finalize_after_convergence(
const unsigned int iteration_index)
1109 if (iteration_index % 2 == 1 || this->beta == Number())
1110 this->x.add(this->alpha, this->p);
1113 using Number =
typename VectorType::value_type;
1114 const unsigned int end_range = this->x.locally_owned_size();
1116 Number *x = this->x.
begin();
1117 Number *r = this->r.begin();
1118 Number *p = this->p.begin();
1124 const Number alpha_plus_previous_alpha_over_beta =
1125 this->alpha + this->previous_alpha / this->beta;
1126 const Number previous_alpha_over_beta =
1127 this->previous_alpha / this->beta;
1130 for (
unsigned int j = 0; j < end_range; ++j)
1132 x[j] += alpha_plus_previous_alpha_over_beta * p[j] -
1133 previous_alpha_over_beta *
1134 this->preconditioner.apply(j, r[j]);
1142 template <
typename U =
void>
1143 std::enable_if_t<!has_apply<PreconditionerType>, U>
1144 operation_before_loop(
const unsigned int iteration_index,
1145 const unsigned int start_range,
1146 const unsigned int end_range)
const
1148 Number *x = this->x.begin() + start_range;
1149 Number *r = this->r.begin() + start_range;
1150 Number *p = this->p.begin() + start_range;
1151 Number *v = this->v.begin() + start_range;
1152 const Number alpha = this->alpha;
1153 const Number beta = this->beta;
1154 constexpr unsigned int grain_size = 128;
1155 std::array<Number, grain_size> prec_r;
1156 if (iteration_index == 1)
1158 for (
unsigned int j = start_range; j < end_range; j += grain_size)
1160 const unsigned int length =
std::min(grain_size, end_range - j);
1161 this->preconditioner.apply_to_subrange(j,
1166 for (
unsigned int i = 0; i < length; ++i)
1176 else if (iteration_index % 2 == 0 && beta != Number())
1178 for (
unsigned int j = start_range; j < end_range; j += grain_size)
1180 const unsigned int length =
std::min(grain_size, end_range - j);
1182 for (
unsigned int i = 0; i < length; ++i)
1183 r[i] -= this->alpha * v[i];
1184 this->preconditioner.apply_to_subrange(j,
1189 for (
unsigned int i = 0; i < length; ++i)
1191 p[i] = this->beta * p[i] + prec_r[i];
1199 else if (iteration_index % 2 == 0 && beta == Number())
1204 for (
unsigned int j = start_range; j < end_range; j += grain_size)
1206 const unsigned int length =
std::min(grain_size, end_range - j);
1208 for (
unsigned int i = 0; i < length; ++i)
1209 r[i] -= this->alpha * v[i];
1210 this->preconditioner.apply_to_subrange(j,
1215 for (
unsigned int i = 0; i < length; ++i)
1217 x[i] += this->alpha * p[i];
1228 const Number alpha_plus_previous_alpha_over_beta =
1229 this->alpha + this->previous_alpha / this->previous_beta;
1230 const Number previous_alpha_over_beta =
1231 this->previous_alpha / this->previous_beta;
1232 for (
unsigned int j = start_range; j < end_range; j += grain_size)
1234 const unsigned int length =
std::min(grain_size, end_range - j);
1235 this->preconditioner.apply_to_subrange(j,
1240 for (
unsigned int i = 0; i < length; ++i)
1242 x[i] += alpha_plus_previous_alpha_over_beta * p[i] -
1243 previous_alpha_over_beta * prec_r[i];
1244 r[i] -= this->alpha * v[i];
1246 this->preconditioner.apply_to_subrange(j,
1251 for (
unsigned int i = 0; i < length; ++i)
1253 p[i] = this->beta * p[i] + prec_r[i];
1267 template <
typename U =
void>
1268 std::enable_if_t<!has_apply<PreconditionerType>, U>
1269 operation_after_loop(
1270 const unsigned int start_range,
1271 const unsigned int end_range,
1274 const Number *r = this->r.begin();
1275 const Number *p = this->p.begin();
1276 const Number *v = this->v.begin();
1277 std::array<VectorizedArray<Number>, 7> my_sums = {};
1278 constexpr unsigned int grain_size = 128;
1281 const unsigned int end_regular =
1282 start_range + (end_range - start_range) / grain_size * grain_size;
1283 std::array<Number, grain_size> prec_r;
1284 std::array<Number, grain_size> prec_v;
1285 for (
unsigned int j = start_range; j < end_regular; j += grain_size)
1287 this->preconditioner.apply_to_subrange(j,
1291 this->preconditioner.apply_to_subrange(j,
1296 for (
unsigned int i = 0; i < grain_size;
1302 prec_rj.
load(prec_r.data() + i);
1303 prec_vj.
load(prec_v.data() + i);
1305 my_sums[0] += pj * vj;
1306 my_sums[1] += vj * vj;
1307 my_sums[2] += rj * vj;
1308 my_sums[3] += rj * rj;
1309 my_sums[4] += rj * prec_vj;
1310 my_sums[5] += vj * prec_vj;
1311 my_sums[6] += rj * prec_rj;
1314 const unsigned int length = end_range - end_regular;
1316 this->preconditioner.apply_to_subrange(end_regular,
1317 end_regular + length,
1320 this->preconditioner.apply_to_subrange(end_regular,
1321 end_regular + length,
1324 for (
unsigned int j = end_regular; j < end_range; ++j)
1326 my_sums[0][0] += p[j] * v[j];
1327 my_sums[1][0] += v[j] * v[j];
1328 my_sums[2][0] += r[j] * v[j];
1329 my_sums[3][0] += r[j] * r[j];
1330 my_sums[4][0] += r[j] * prec_v[j - end_regular];
1331 my_sums[5][0] += v[j] * prec_v[j - end_regular];
1332 my_sums[6][0] += r[j] * prec_r[j - end_regular];
1334 for (
unsigned int i = 0; i < vectorized_sums.size(); ++i)
1335 vectorized_sums[i] += my_sums[i];
1341 template <
typename U =
void>
1342 std::enable_if_t<!has_apply<PreconditionerType>, U>
1343 finalize_after_convergence(
const unsigned int iteration_index)
1345 if (iteration_index % 2 == 1 || this->beta == Number())
1346 this->x.add(this->alpha, this->p);
1349 const unsigned int end_range = this->x.locally_owned_size();
1351 Number *x = this->x.begin();
1352 Number *r = this->r.begin();
1353 Number *p = this->p.begin();
1354 const Number alpha_plus_previous_alpha_over_beta =
1355 this->alpha + this->previous_alpha / this->beta;
1356 const Number previous_alpha_over_beta =
1357 this->previous_alpha / this->beta;
1359 constexpr unsigned int grain_size = 128;
1360 std::array<Number, grain_size> prec_r;
1361 for (
unsigned int j = 0; j < end_range; j += grain_size)
1363 const unsigned int length =
std::min(grain_size, end_range - j);
1364 this->preconditioner.apply_to_subrange(j,
1369 for (
unsigned int i = 0; i < length; ++i)
1370 x[i] += alpha_plus_previous_alpha_over_beta * p[i] -
1371 previous_alpha_over_beta * prec_r[i];
1385template <
typename VectorType>
1387template <
typename MatrixType,
typename PreconditionerType>
1393 const VectorType &b,
1394 const PreconditionerType &preconditioner)
1396 using number =
typename VectorType::value_type;
1403 const bool do_eigenvalues =
1404 !condition_number_signal.empty() || !all_condition_numbers_signal.empty() ||
1405 !eigenvalues_signal.empty() || !all_eigenvalues_signal.empty();
1408 std::vector<typename VectorType::value_type>
diagonal;
1409 std::vector<typename VectorType::value_type> offdiagonal;
1411 typename VectorType::value_type eigen_beta_alpha = 0;
1415 internal::SolverCG::
1416 IterationWorker<VectorType, MatrixType, PreconditionerType>
1419 determine_beta_by_flexible_formula,
1427 solver_state = this->iteration_status(0, worker.residual_norm, x);
1435 worker.do_iteration(it);
1437 print_vectors(it, x, worker.r, worker.p);
1441 this->coefficients_signal(worker.previous_alpha, worker.beta);
1446 diagonal.push_back(number(1.) / worker.previous_alpha +
1448 eigen_beta_alpha = worker.beta / worker.previous_alpha;
1449 offdiagonal.push_back(
std::sqrt(worker.beta) /
1450 worker.previous_alpha);
1452 compute_eigs_and_cond(diagonal,
1454 all_eigenvalues_signal,
1455 all_condition_numbers_signal);
1458 solver_state = this->iteration_status(it, worker.residual_norm, x);
1461 worker.finalize_after_convergence(it);
1463 compute_eigs_and_cond(diagonal,
1466 condition_number_signal);
1474template <
typename VectorType>
1477 const std::function<
void(
typename VectorType::value_type,
1478 typename VectorType::value_type)> &slot)
1480 return coefficients_signal.connect(slot);
1485template <
typename VectorType>
1488 const std::function<
void(
double)> &slot,
1489 const bool every_iteration)
1491 if (every_iteration)
1493 return all_condition_numbers_signal.connect(slot);
1497 return condition_number_signal.connect(slot);
1503template <
typename VectorType>
1506 const std::function<
void(
const std::vector<double> &)> &slot,
1507 const bool every_iteration)
1509 if (every_iteration)
1511 return all_eigenvalues_signal.connect(slot);
1515 return eigenvalues_signal.connect(slot);
1521template <
typename VectorType>
1524 const bool use_default_residual)
1525 : use_default_residual(use_default_residual)
1529template <
typename VectorType>
1533 const AdditionalData &
data)
1536 this->determine_beta_by_flexible_formula =
true;
1537 this->additional_data =
data;
1542template <
typename VectorType>
1545 const AdditionalData &
data)
1548 this->determine_beta_by_flexible_formula =
true;
1549 this->additional_data =
data;
SolverCG(SolverControl &cn, VectorMemory< VectorType > &mem, const AdditionalData &data=AdditionalData())
virtual void print_vectors(const unsigned int step, const VectorType &x, const VectorType &r, const VectorType &d) const
boost::signals2::connection connect_condition_number_slot(const std::function< void(double)> &slot, const bool every_iteration=false)
boost::signals2::connection connect_eigenvalues_slot(const std::function< void(const std::vector< double > &)> &slot, const bool every_iteration=false)
boost::signals2::connection connect_coefficients_slot(const std::function< void(typename VectorType::value_type, typename VectorType::value_type)> &slot)
virtual ~SolverCG() override=default
void solve(const MatrixType &A, VectorType &x, const VectorType &b, const PreconditionerType &preconditioner)
SolverCG(SolverControl &cn, const AdditionalData &data=AdditionalData())
static void compute_eigs_and_cond(const std::vector< typename VectorType::value_type > &diagonal, const std::vector< typename VectorType::value_type > &offdiagonal, const boost::signals2::signal< void(const std::vector< double > &)> &eigenvalues_signal, const boost::signals2::signal< void(double)> &cond_signal)
@ iterate
Continue iteration.
@ success
Stop iteration, goal reached.
AdditionalData additional_data
SolverFlexibleCG(SolverControl &cn, const AdditionalData &data=AdditionalData())
SolverFlexibleCG(SolverControl &cn, VectorMemory< VectorType > &mem, const AdditionalData &data=AdditionalData())
constexpr VectorizedArrayIterator< VectorizedArrayType > begin()
static constexpr std::size_t size()
void store(OtherNumber *ptr) const
void load(const OtherNumber *ptr)
#define DEAL_II_OPENMP_SIMD_PRAGMA
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_CXX20_REQUIRES(condition)
#define DEAL_II_NAMESPACE_CLOSE
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcDivideByZero()
#define AssertThrow(cond, exc)
std::vector< index_type > data
@ diagonal
Matrix is diagonal.
Tpetra::Vector< Number, LO, GO, NodeType< MemorySpace > > VectorType
Tpetra::CrsMatrix< Number, LO, GO, NodeType< MemorySpace > > MatrixType
Tensor< 2, dim, Number > l(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
SymmetricTensor< 2, dim, Number > b(const Tensor< 2, dim, Number > &F)
VectorType::value_type * end(VectorType &V)
VectorType::value_type * begin(VectorType &V)
T sum(const T &t, const MPI_Comm mpi_communicator)
::VectorizedArray< Number, width > min(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > sqrt(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > abs(const ::VectorizedArray< Number, width > &)
unsigned int global_dof_index
AdditionalData(const bool use_default_residual=true)
bool use_default_residual
bool use_default_residual
AdditionalData(const bool use_default_residual=true)
std::array< Number, 1 > eigenvalues(const SymmetricTensor< 2, 1, Number > &T)