24 using Tlhs =
typename FieldLHS::value_type;
28 constexpr static unsigned Dim = FieldLHS::dim;
29 using typename Base::lhs_type,
typename Base::rhs_type;
30 using OperatorRet = UnaryMinus<detail::meta_laplace<lhs_type>>;
31 using LowerRet = UnaryMinus<detail::meta_lower_laplace<lhs_type>>;
32 using UpperRet = UnaryMinus<detail::meta_upper_laplace<lhs_type>>;
33 using UpperAndLowerRet = UnaryMinus<detail::meta_upper_and_lower_laplace<lhs_type>>;
34 using InverseDiagonalRet = double;
35 using DiagRet = double;
40 static_assert(std::is_floating_point<Tlhs>::value,
"Not a floating point type");
47 static_assert(std::is_floating_point<Tlhs>::value,
"Not a floating point type");
49 setSolver(*(this->lhs_mp));
52 void setLhs(lhs_type& lhs)
override {
57 void setSolver(lhs_type lhs) {
58 std::string solver_type = this->params_m.template get<std::string>(
"solver");
59 typename lhs_type::Mesh_t mesh = lhs.get_mesh();
60 typename lhs_type::Layout_t layout = lhs.getLayout();
63 if (solver_type ==
"preconditioned") {
65 std::make_unique<
PCG<OperatorRet, LowerRet, UpperRet, UpperAndLowerRet,
66 InverseDiagonalRet, DiagRet, FieldLHS, FieldRHS>>());
69 std::string preconditioner_type =
70 this->params_m.template get<std::string>(
"preconditioner_type");
71 preconditioner_validation::throwIfUnknownType(preconditioner_type,
"PoissonCG::setSolver");
74 int level = this->params_m.template get<int>(
"newton_level");
75 int degree = this->params_m.template get<int>(
"chebyshev_degree");
76 int inner = this->params_m.template get<int>(
"gauss_seidel_inner_iterations");
77 int outer = this->params_m.template get<int>(
"gauss_seidel_outer_iterations");
78 double omega = this->params_m.template get<double>(
"ssor_omega");
79 int richardson_iterations =
80 this->params_m.template get<int>(
"richardson_iterations");
81 int communication = this->params_m.template get<int>(
"communication");
87 preconditioner_validation::sanitizeParams(preconditioner_type, warn, level, degree,
88 richardson_iterations, inner, outer, omega,
96 for (
unsigned int d = 0; d < Dim; ++d) {
97 n = mesh.getGridsize(d);
98 h = mesh.getMeshSpacing(d);
99 double local_min = 4 / std::pow(h, 2);
100 double local_max = 0;
102 for (
unsigned int i = 1; i < n; ++i) {
103 test = 4. / std::pow(h, 2) * std::pow(std::sin(i * M_PI * h / 2.), 2);
104 if (test > local_max) {
107 if (test < local_min) {
115 algo_m->setPreconditioner(
116 IPPL_SOLVER_OPERATOR_WRAPPER(-
laplace, lhs_type),
121 IPPL_SOLVER_OPERATOR_WRAPPER(diagonal_laplace, lhs_type), alpha, beta,
122 preconditioner_type, level, degree, richardson_iterations, inner, outer,
125 algo_m->setPreconditioner(
126 IPPL_SOLVER_OPERATOR_WRAPPER(-
laplace, lhs_type),
131 IPPL_SOLVER_OPERATOR_WRAPPER(diagonal_laplace, lhs_type), alpha, beta,
132 preconditioner_type, level, degree, richardson_iterations, inner, outer,
137 std::make_unique<CG<OperatorRet, LowerRet, UpperRet, UpperAndLowerRet,
138 InverseDiagonalRet, DiagRet, FieldLHS, FieldRHS>>());
140 algo_m->initializeFields(lhs.get_mesh(), lhs.getLayout());
146 algo_m->setOperator(IPPL_SOLVER_OPERATOR_WRAPPER(-
laplace, lhs_type));
147 algo_m->operator()(*(this->lhs_mp), *(this->rhs_mp), this->params_m);
149 int output = this->params_m.template get<int>(
"output_type");
150 if (output & Base::GRAD) {
151 *(this->grad_mp) = -
grad(*(this->lhs_mp));
169 std::unique_ptr<
CG<OperatorRet, LowerRet, UpperRet, UpperAndLowerRet, InverseDiagonalRet,
170 DiagRet, FieldLHS, FieldRHS>>
174 this->params_m.
add(
"max_iterations", 2000);
175 this->params_m.
add(
"tolerance", (Tlhs)1e-13);
176 this->params_m.
add(
"solver",
"non-preconditioned");