7#ifndef IPPL_PRECONDITIONER_H
8#define IPPL_PRECONDITIONER_H
15#define IPPL_SOLVER_OPERATOR_WRAPPER(fun, type) \
21 template <
typename Field>
57 template <
typename Field,
typename InvDiagF>
72 Field res(mesh, layout);
88 template <
typename Field,
typename OperatorF>
95 unsigned int max_level = 6,
double zeta = 1e-3,
96 double* eta =
nullptr)
103 op_m = std::move(op);
108 if (
eta_m !=
nullptr) {
132 if (
eta_m ==
nullptr) {
141 for (
unsigned int i = 2; i <
level_m + 1; ++i) {
146 Field res(mesh, layout);
153 Field PAPr(mesh, layout);
154 Field Pr(mesh, layout);
159 res =
eta_m[level] * (2.0 * Pr - PAPr);
179 template <
typename Field,
typename OperatorF>
186 unsigned int degree = 63,
double zeta = 1e-3)
193 op_m = std::move(op);
198 if (
rho_m !=
nullptr) {
226 Field res(mesh, layout);
227 Field x(mesh, layout);
228 Field x_old(mesh, layout);
229 Field A(mesh, layout);
230 Field z(mesh, layout);
233 if (
rho_m ==
nullptr) {
241 for (
unsigned int i = 1; i <
degree_m + 1; ++i) {
259 for (
unsigned int i = 2; i <
degree_m + 1; ++i) {
284 template <
typename Field,
typename UpperAndLowerF,
typename InvDiagF>
291 unsigned innerloops = 5)
301 Field g(mesh, layout);
315 if constexpr (std::is_same_v<InvDiagF, std::function<double(
Field)>>) {
345 template <
typename Field,
typename OperatorF,
typename InvDiagF>
352 unsigned innerloops = 5)
355 op_m = std::move(op);
362 Field g(mesh, layout);
363 Field g_old(mesh, layout);
378 if constexpr (std::is_same_v<InvDiagF, std::function<double(
Field)>>) {
405 template <
typename Field,
typename LowerF,
typename UpperF,
typename InvDiagF>
412 unsigned innerloops,
unsigned outerloops)
425 Field x(mesh, layout);
442 if constexpr (std::is_same_v<InvDiagF, std::function<double(
Field)>>) {
460 if constexpr (std::is_same_v<InvDiagF, std::function<double(
Field)>>) {
491 template <
typename Field,
typename LowerF,
typename UpperF,
typename InvDiagF,
typename DiagF>
498 DiagF&& diagonal,
unsigned innerloops,
unsigned outerloops,
519 Field x(mesh, layout);
536 if constexpr (std::is_same_v<InvDiagF, std::function<double(
Field)>>) {
603 template <
typename Field,
typename Functor>
604 double powermethod(Functor&& f,
Field& x_0,
unsigned int max_iter = 5000,
double tol = 1e-3) {
610 Field x_new(mesh, layout);
611 Field x_diff(mesh, layout);
614 while (error > tol && i < max_iter) {
616 lambda =
norm(x_new);
617 x_diff = x_new - lambda * x_0;
618 error =
norm(x_diff);
619 x_new = x_new / lambda;
624 std::cerr <<
"Powermethod did not converge, lambda_max : " << lambda
625 <<
", error : " << error << std::endl;
638 template <
typename Field,
typename Functor>
640 unsigned int max_iter = 5000,
double tol = 1e-3) {
646 Field x_new(mesh, layout);
647 Field x_diff(mesh, layout);
650 while (error > tol && i < max_iter) {
652 x_new = x_new - lambda_max * x_0;
653 lambda = -
norm(x_new);
654 x_diff = x_new - lambda * x_0;
655 error =
norm(x_diff);
656 x_new = x_new / -lambda;
660 lambda = lambda + lambda_max;
662 std::cerr <<
"Powermethod did not converge, lambda_min : " << lambda
663 <<
", error : " << error << std::endl;
ippl::Field< T, Dim, Mesh_t< Dim >, Centering_t< Dim >, ViewArgs... > Field
double powermethod(Functor &&f, Field &x_0, unsigned int max_iter=5000, double tol=1e-3)
double adapted_powermethod(Functor &&f, Field &x_0, double lambda_max, unsigned int max_iter=5000, double tol=1e-3)
T norm(const FEMVector< T > &v, int p=2)
Layout_t & getLayout() const
static constexpr unsigned dim
KOKKOS_INLINE_FUNCTION Mesh_t & get_mesh() const
FieldLayout< Dim > Layout_t
virtual ~preconditioner()=default
static constexpr unsigned Dim
preconditioner(std::string name)
typename Field::Layout_t layout_type
virtual Field operator()(Field &u)
virtual void init_fields(Field &b)
typename Field::Mesh_t mesh_type
jacobi_preconditioner(InvDiagF &&inverse_diagonal, double w=1.0)
InvDiagF inverse_diagonal_m
typename Field::Layout_t layout_type
static constexpr unsigned Dim
Field operator()(Field &u) override
typename Field::Mesh_t mesh_type
Field recursive_preconditioner(Field &u, unsigned int level)
static constexpr unsigned Dim
typename Field::Layout_t layout_type
polynomial_newton_preconditioner(const polynomial_newton_preconditioner &other)
polynomial_newton_preconditioner & operator=(const polynomial_newton_preconditioner &other)
polynomial_newton_preconditioner(OperatorF &&op, double alpha, double beta, unsigned int max_level=6, double zeta=1e-3, double *eta=nullptr)
Field operator()(Field &u) override
~polynomial_newton_preconditioner()
typename Field::Mesh_t mesh_type
polynomial_chebyshev_preconditioner(const polynomial_chebyshev_preconditioner &other)
static constexpr unsigned Dim
typename Field::Mesh_t mesh_type
polynomial_chebyshev_preconditioner & operator=(const polynomial_chebyshev_preconditioner &other)
~polynomial_chebyshev_preconditioner()
polynomial_chebyshev_preconditioner(OperatorF &&op, double alpha, double beta, unsigned int degree=63, double zeta=1e-3)
typename Field::Layout_t layout_type
Field operator()(Field &r) override
Field operator()(Field &r) override
void init_fields(Field &b) override
richardson_preconditioner(UpperAndLowerF &&upper_and_lower, InvDiagF &&inverse_diagonal, unsigned innerloops=5)
typename Field::Mesh_t mesh_type
static constexpr unsigned Dim
InvDiagF inverse_diagonal_m
UpperAndLowerF upper_and_lower_m
typename Field::Layout_t layout_type
richardson_preconditioner_alt(OperatorF &&op, InvDiagF &&inverse_diagonal, unsigned innerloops=5)
typename Field::Mesh_t mesh_type
Field operator()(Field &r) override
void init_fields(Field &b) override
static constexpr unsigned Dim
typename Field::Layout_t layout_type
InvDiagF inverse_diagonal_m
gs_preconditioner(LowerF &&lower, UpperF &&upper, InvDiagF &&inverse_diagonal, unsigned innerloops, unsigned outerloops)
typename Field::Layout_t layout_type
typename Field::Mesh_t mesh_type
Field operator()(Field &b) override
static constexpr unsigned Dim
InvDiagF inverse_diagonal_m
void init_fields(Field &b) override
static constexpr unsigned Dim
ssor_preconditioner(LowerF &&lower, UpperF &&upper, InvDiagF &&inverse_diagonal, DiagF &&diagonal, unsigned innerloops, unsigned outerloops, double omega)
void init_fields(Field &b) override
Field operator()(Field &b) override
typename Field::Layout_t layout_type
InvDiagF inverse_diagonal_m
typename Field::Mesh_t mesh_type
Timing::TimerRef TimerRef
static TimerRef getTimer(const char *nm)
static void stopTimer(TimerRef t)
static void startTimer(TimerRef t)