IPPL API Reference
Independent Parallel Particle Layer C++ API
Loading...
Searching...
No Matches
FEMMaxwellDiffusionSolver.h
1// Class FEMMaxwellDifussionSolver
2// Solves the electric diffusion probelm given by curl(curl(E)) + E = f in
3// the domain and n x E = 0 on the boundary.
4
5#ifndef IPPL_FEM_MAXWELL_DIFFUSION_SOLVER_H
6#define IPPL_FEM_MAXWELL_DIFFUSION_SOLVER_H
7
8#include <fstream>
9#include <iomanip>
10#include <iostream>
11
12#include "FEM/FEMQuadratureData.h"
13#include "LinearSolvers/PCG.h"
14#include "Maxwell.h"
15
16namespace ippl {
17
28 template <typename T, unsigned Dim, unsigned numElementDOFs>
29 struct EvalFunctor {
37
44 const T absDetDPhi;
45
52
70 KOKKOS_FUNCTION auto operator()(
71 size_t i, size_t j,
72 const QuadratureData<Vector<T, Dim>, Vector<T, Dim>, numElementDOFs>& qd) const {
73 T curlTerm = dot(DPhiInvT * qd.deriv_q[j], DPhiInvT * qd.deriv_q[i]).apply();
74 T massTerm = dot(qd.val_q[j], qd.val_q[i]).apply();
75 return (curlTerm + massTerm) * absDetDPhi;
76 }
77 };
78
87 template <typename FieldType>
88 class FEMMaxwellDiffusionSolver : public Maxwell<FieldType, FieldType> {
89 constexpr static unsigned Dim = FieldType::dim;
90
91 // we call value_type twice as in theory we expect the field to store
92 // vector data represented by an ippl::Vector
93 using T = typename FieldType::value_type::value_type;
94
95 typedef Vector<T, Dim> point_t;
96
97 public:
99 using MeshType = typename FieldType::Mesh_t;
100
101 // PCG (Preconditioned Conjugate Gradient) is the solver algorithm used
104
105 // FEM Space types
106 using ElementType =
107 std::conditional_t<Dim == 2, ippl::QuadrilateralElement<T>, ippl::HexahedralElement<T>>;
108
110
112
113 // default constructor (compatibility with Alpine)
115 : Base()
116 , rhsVector_m(nullptr)
117 , refElement_m()
118 , quadrature_m(refElement_m, 0.0, 0.0)
122
123 FEMMaxwellDiffusionSolver(FieldType& lhs, FieldType& rhs,
124 const FEMVector<point_t>& rhsVector)
125 : Base(lhs, lhs, rhs)
126 , rhsVector_m(nullptr)
127 , refElement_m()
128 , quadrature_m(refElement_m, 0.0, 0.0)
129 , nedelecSpace_m(rhs.get_mesh(), refElement_m, quadrature_m, rhs.getLayout()) {
130 static_assert(std::is_floating_point<T>::value, "Not a floating point type");
132
133 // Calcualte the rhs, using the Nedelec space
135 std::make_unique<FEMVector<T>>(nedelecSpace_m.evaluateLoadVector(rhsVector));
136
137 rhsVector_m->accumulateHalo();
138 rhsVector_m->fillHalo();
139 }
140
141 void setRhs(FieldType& rhs, const FEMVector<point_t>& rhsVector) {
142 Base::setRhs(rhs);
143
144 // Calcualte the rhs, using the Nedelec space
146 std::make_unique<FEMVector<T>>(nedelecSpace_m.evaluateLoadVector(rhsVector));
147
148 rhsVector_m->accumulateHalo();
149 rhsVector_m->fillHalo();
150 }
151
155 void solve() override {
156 const Vector<size_t, Dim> zeroNdIndex = Vector<size_t, Dim>(0);
157
158 // We can pass the zeroNdIndex here, since the transformation
159 // jacobian does not depend on translation
160 const auto firstElementVertexPoints =
162
163 // Compute Inverse Transpose Transformation Jacobian ()
164 const Vector<T, Dim> DPhiInvT =
165 refElement_m.getInverseTransposeTransformationJacobian(firstElementVertexPoints);
166
167 // Compute absolute value of the determinant of the transformation
168 // jacobian (|det D Phi_K|)
169 const T absDetDPhi = Kokkos::abs(
170 refElement_m.getDeterminantOfTransformationJacobian(firstElementVertexPoints));
171
172 // Create the functor object which stores the function we have to
173 // solve for the lhs
174 EvalFunctor<T, Dim, NedelecType::numElementDOFs> maxwellDiffusionEval(DPhiInvT,
175 absDetDPhi);
176
177 // The Ax operator
178 const auto algoOperator = [maxwellDiffusionEval,
179 this](FEMVector<T> vector) -> FEMVector<T> {
180 vector.fillHalo();
181
182 FEMVector<T> return_vector =
183 nedelecSpace_m.evaluateAx(vector, maxwellDiffusionEval);
184
185 return_vector.accumulateHalo();
186
187 return return_vector;
188 };
189
190 // setup the CG solver
191 pcg_algo_m.setOperator(algoOperator);
192
193 // Create the coefficient vector for the solution
194 FEMVector<T> lhsVector = rhsVector_m->deepCopy();
195
196 // Solve the system using CG
197 try {
198 pcg_algo_m(lhsVector, *rhsVector_m, this->params_m);
199 } catch (IpplException& e) {
200 std::string msg = e.where() + ": " + e.what() + "\n";
201 Kokkos::abort(msg.c_str());
202 }
203
204 // store solution.
205 lhsVector_m = std::make_unique<FEMVector<T>>(lhsVector);
206
207 // set the boundary values to the correct values.
208 lhsVector.fillHalo();
209 }
210
217
222 T getResidue() const { return pcg_algo_m.getResidue(); }
223
247 Kokkos::View<point_t*> reconstructToPoints(const Kokkos::View<point_t*>& positions) {
248 return this->nedelecSpace_m.reconstructToPoints(positions, *lhsVector_m);
249 }
250
258 template <typename F>
259 T getL2Error(const F& analytic) {
260 T error_norm = this->nedelecSpace_m.computeError(*lhsVector_m, analytic);
261 return error_norm;
262 }
263
264 protected:
269
274 virtual void setDefaultParameters() {
275 this->params_m.add("max_iterations", 10);
276 this->params_m.add("tolerance", (T)1e-13);
277 }
278
284 std::unique_ptr<FEMVector<T>> rhsVector_m;
285
291 std::unique_ptr<FEMVector<T>> lhsVector_m;
292
296 ElementType refElement_m;
297
302
310 };
311
312} // namespace ippl
313
314#endif // IPPL_FEM_MAXWELL_DIFFUSION_SOLVER_H
Definition IpplException.h:6
virtual int getIterationCount()
Definition PCG.h:106
virtual void setOperator(OperatorF op)
Definition PCG.h:70
A solver for the electric diffusion equation given by and using the Nédélec basis functions.
Definition FEMMaxwellDiffusionSolver.h:88
std::unique_ptr< FEMVector< T > > rhsVector_m
FEM represenation of the rhs We use this to store the rhs b of the System Ax = b used in the Galerkin...
Definition FEMMaxwellDiffusionSolver.h:284
virtual void setDefaultParameters()
Sets the default values for the CG solver. Defaults are: max Iterations = 10, tolerance = 1e-13.
Definition FEMMaxwellDiffusionSolver.h:274
Kokkos::View< point_t * > reconstructToPoints(const Kokkos::View< point_t * > &positions)
Reconstructs function values at arbitrary points in the mesh.
Definition FEMMaxwellDiffusionSolver.h:247
void solve() override
Solve the equation using finite element methods.
Definition FEMMaxwellDiffusionSolver.h:155
T getL2Error(const F &analytic)
Given an analytical solution computes the L2 norm error.
Definition FEMMaxwellDiffusionSolver.h:259
QuadratureType quadrature_m
The quadrature rule we use.
Definition FEMMaxwellDiffusionSolver.h:301
T getResidue() const
Definition FEMMaxwellDiffusionSolver.h:222
PCGSolverAlgorithm_t pcg_algo_m
The CG Solver we use.
Definition FEMMaxwellDiffusionSolver.h:268
int getIterationCount()
Definition FEMMaxwellDiffusionSolver.h:216
ElementType refElement_m
the reference element we have.
Definition FEMMaxwellDiffusionSolver.h:296
NedelecType nedelecSpace_m
The Nedelec Space object.
Definition FEMMaxwellDiffusionSolver.h:309
std::unique_ptr< FEMVector< T > > lhsVector_m
FEM represenation of the solution vector We use this to store the solution x of the System Ax = b use...
Definition FEMMaxwellDiffusionSolver.h:291
1D vector used in the context of FEM.
Definition FEMVector.h:34
void fillHalo()
Copy values from neighboring ranks into local halo.
Definition FEMVector.hpp:38
void accumulateHalo()
Accumulate halo values in neighbor.
Definition FEMVector.hpp:95
FEMVector< T > deepCopy() const
Create a deep copy, where all the information of this vector is copied to a new one.
Definition FEMVector.hpp:234
KOKKOS_FUNCTION vertex_points_t getElementMeshVertexPoints(const indices_t &elementNDIndex) const
Get all the global vertex points of an element (given by its NDIndex).
Definition FiniteElementSpace.hpp:271
Definition HexahedralElement.h:14
Definition Maxwell.h:20
Definition NDIndex.h:21
FEMVector< T > evaluateAx(FEMVector< T > &x, F &evalFunction) const
Assembly operations ///////////////////////////////////////////////.
Definition NedelecSpace.hpp:372
T computeError(const FEMVector< T > &u_h, const F &u_sol) const
Error norm computations ///////////////////////////////////////////.
Definition NedelecSpace.hpp:912
FEMVector< T > evaluateLoadVector(const FEMVector< point_t > &f) const
Assemble the load vector b of the system Ax = b, given a field of the right hand side defined at the ...
Definition NedelecSpace.hpp:494
Kokkos::View< point_t * > reconstructToPoints(const Kokkos::View< point_t * > &positions, const FEMVector< T > &coef) const
Reconstructs function values at arbitrary points in the mesh given the Nedelec DOF coefficients.
Definition NedelecSpace.hpp:830
void add(const std::string &key, const T &value)
Definition ParameterList.h:44
Definition Vector.h:23
Definition Archive.h:20
Representation of the lhs of the problem we are trying to solve.
Definition FEMMaxwellDiffusionSolver.h:29
KOKKOS_FUNCTION auto operator()(size_t i, size_t j, const QuadratureData< Vector< T, Dim >, Vector< T, Dim >, numElementDOFs > &qd) const
Returns the evaluation of (curl(b_i)*curl(b_j) + b_i*b_j)*absDetDPhi.
Definition FEMMaxwellDiffusionSolver.h:70
const T absDetDPhi
The determinant of the Jacobian.
Definition FEMMaxwellDiffusionSolver.h:44
const Vector< T, Dim > DPhiInvT
The inverse transpose Jacobian.
Definition FEMMaxwellDiffusionSolver.h:36
EvalFunctor(Vector< T, Dim > DPhiInvT, T absDetDPhi)
Constructor.
Definition FEMMaxwellDiffusionSolver.h:49
Per-quadrature-node basis data passed to evaluateAx evaluator functors.
Definition FEMQuadratureData.h:18