IPPL (Independent Parallel Particle Layer)
IPPL
Loading...
Searching...
No Matches
PoissonCG.h
Go to the documentation of this file.
1//
2// Class PoissonCG
3// Solves the Poisson problem with the CG algorithm
4//
5
6#ifndef IPPL_POISSON_CG_H
7#define IPPL_POISSON_CG_H
8
9#include "LaplaceHelpers.h"
10#include "LinearSolvers/PCG.h"
11#include "Poisson.h"
12namespace ippl {
13
14// Expands to a lambda that acts as a wrapper for a differential operator
15// fun: the function for which to create the wrapper, such as ippl::laplace
16// type: the argument type, which should match the LHS type for the solver
17#define IPPL_SOLVER_OPERATOR_WRAPPER(fun, type) \
18 [](type arg) { \
19 return fun(arg); \
20 }
21
22 template <typename FieldLHS, typename FieldRHS = FieldLHS>
23 class PoissonCG : public Poisson<FieldLHS, FieldRHS> {
24 using Tlhs = typename FieldLHS::value_type;
25
26 public:
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;
36
38 : Base()
39 , algo_m(nullptr) {
40 static_assert(std::is_floating_point<Tlhs>::value, "Not a floating point type");
42 }
43
45 : Base(lhs, rhs)
46 , algo_m(nullptr) {
47 static_assert(std::is_floating_point<Tlhs>::value, "Not a floating point type");
49 }
50
51 void setSolver(lhs_type lhs) {
52 std::string solver_type = this->params_m.template get<std::string>("solver");
53 typename lhs_type::Mesh_t mesh = lhs.get_mesh();
54 typename lhs_type::Layout_t layout = lhs.getLayout();
55 double beta = 0;
56 double alpha = 0;
57 if (solver_type == "preconditioned") {
58 algo_m = std::move(
60 InverseDiagonalRet, DiagRet, FieldLHS, FieldRHS>>());
61 std::string preconditioner_type =
62 this->params_m.template get<std::string>("preconditioner_type");
63 int level = this->params_m.template get<int>("newton_level");
64 int degree = this->params_m.template get<int>("chebyshev_degree");
65 int inner = this->params_m.template get<int>("gauss_seidel_inner_iterations");
66 int outer = this->params_m.template get<int>("gauss_seidel_outer_iterations");
67 double omega = this->params_m.template get<double>("ssor_omega");
68 int richardson_iterations =
69 this->params_m.template get<int>("richardson_iterations");
70 int communication = this->params_m.template get<int>("communication");
71 // Analytical eigenvalues for the d dimensional laplace operator
72 // Going brute force through all possible eigenvalues seems to be the only way to
73 // find max and min
74
75 unsigned long n;
76 double h;
77 for (unsigned int d = 0; d < Dim; ++d) {
78 n = mesh.getGridsize(d);
79 h = mesh.getMeshSpacing(d);
80 double local_min = 4 / std::pow(h, 2); // theoretical maximum
81 double local_max = 0;
82 double test;
83 for (unsigned int i = 1; i < n; ++i) {
84 test = 4. / std::pow(h, 2) * std::pow(std::sin(i * M_PI * h / 2.), 2);
85 if (test > local_max) {
86 local_max = test;
87 }
88 if (test < local_min) {
89 local_min = test;
90 }
91 }
92 beta += local_max;
93 alpha += local_min;
94 }
95 if (communication) {
96 algo_m->setPreconditioner(
103 preconditioner_type, level, degree, richardson_iterations, inner, outer,
104 omega);
105 } else {
106 algo_m->setPreconditioner(
113 preconditioner_type, level, degree, richardson_iterations, inner, outer,
114 omega);
115 }
116 } else {
117 algo_m = std::move(
118 std::make_unique<CG<OperatorRet, LowerRet, UpperRet, UpperAndLowerRet,
119 InverseDiagonalRet, DiagRet, FieldLHS, FieldRHS>>());
120 }
121 }
122
123 void solve() override {
124 setSolver(*(this->lhs_mp));
126 algo_m->operator()(*(this->lhs_mp), *(this->rhs_mp), this->params_m);
127
128 int output = this->params_m.template get<int>("output_type");
129 if (output & Base::GRAD) {
130 *(this->grad_mp) = -grad(*(this->lhs_mp));
131 }
132 }
133
139 int getIterationCount() { return algo_m->getIterationCount(); }
140
145 Tlhs getResidue() const { return algo_m->getResidue(); }
146
147 protected:
149 DiagRet, FieldLHS, FieldRHS>>
151
152 void setDefaultParameters() override {
153 this->params_m.add("max_iterations", 2000);
154 this->params_m.add("tolerance", (Tlhs)1e-13);
155 this->params_m.add("solver", "non-preconditioned");
156 }
157 };
158
159} // namespace ippl
160
161#endif
#define IPPL_SOLVER_OPERATOR_WRAPPER(fun, type)
Definition Archive.h:20
detail::meta_upper_laplace< Field > upper_laplace(Field &u)
detail::meta_upper_and_lower_laplace< Field > upper_and_lower_laplace_no_comm(Field &u)
detail::meta_lower_laplace< Field > lower_laplace(Field &u)
double negative_inverse_diagonal_laplace(Field &u)
detail::meta_upper_laplace< Field > upper_laplace_no_comm(Field &u)
double diagonal_laplace(Field &u)
detail::meta_grad< Field > grad(Field &u)
detail::meta_laplace< Field > laplace(Field &u)
detail::meta_lower_laplace< Field > lower_laplace_no_comm(Field &u)
KOKKOS_INLINE_FUNCTION auto & get(Tuple< Ts... > &t)
Accessor function to get an element mutable reference at a specific index from a Tuple.
Definition Tuple.h:314
detail::meta_upper_and_lower_laplace< Field > upper_and_lower_laplace(Field &u)
Layout_t & getLayout() const
Definition BareField.h:134
Mesh Mesh_t
Definition Field.h:23
KOKKOS_INLINE_FUNCTION Mesh_t & get_mesh() const
Definition Field.h:64
FieldLayout< Dim > Layout_t
Definition Field.h:25
Definition PCG.h:17
virtual KOKKOS_INLINE_FUNCTION const vector_type & getMeshSpacing() const =0
KOKKOS_INLINE_FUNCTION const vector_type & getGridsize() const
Definition Mesh.hpp:20
FieldRHS rhs_type
Definition Poisson.h:25
FieldLHS lhs_type
Definition Poisson.h:24
int getIterationCount()
Definition PoissonCG.h:139
UnaryMinus< detail::meta_upper_laplace< lhs_type > > UpperRet
Definition PoissonCG.h:32
UnaryMinus< detail::meta_upper_and_lower_laplace< lhs_type > > UpperAndLowerRet
Definition PoissonCG.h:33
typename Field< T, Dim >::value_type Tlhs
Definition PoissonCG.h:24
void solve() override
Definition PoissonCG.h:123
UnaryMinus< detail::meta_lower_laplace< lhs_type > > LowerRet
Definition PoissonCG.h:31
void setDefaultParameters() override
Definition PoissonCG.h:152
std::unique_ptr< CG< OperatorRet, LowerRet, UpperRet, UpperAndLowerRet, InverseDiagonalRet, DiagRet, Field< T, Dim >, Field_t< Dim > > > algo_m
Definition PoissonCG.h:150
UnaryMinus< detail::meta_laplace< lhs_type > > OperatorRet
Definition PoissonCG.h:30
PoissonCG(lhs_type &lhs, rhs_type &rhs)
Definition PoissonCG.h:44
void setSolver(lhs_type lhs)
Definition PoissonCG.h:51
Tlhs getResidue() const
Definition PoissonCG.h:145
Poisson< Field< T, Dim >, Field_t< Dim > > Base
Definition PoissonCG.h:27