Files
NuFI_deal.ii/nufi/fields.h

136 lines
4.1 KiB
C++

#ifndef FIELDS_H
#define FIELDS_H
#include "nufi/parameters.h"
#include "nufi/poisson_problem.h"
#include <cmath>
#include <cstddef>
#include <deal.II/base/function.h>
#include <deal.II/base/point.h>
#include <vector>
using namespace dealii;
// inline std::vector<int> Indices_of_points(const std::vector<double> &points,
// double x_min, double x_max, double dx, int grid_type=0)
// {
// // grid type:
// // 0 => uniform
// // 1 => non uniform (TODO)
//
// if (dx <= 0.0) {
// throw std::invalid_argument("dx must be positive");
// }
// if (x_max <= x_min) {
// throw std::invalid_argument("x_max must be > x_min");
// }
//
// std::vector<int> indices;
// indices.reserve(points.size());
//
// switch (grid_type) {
// case 0:
// {
// const double L = x_max - x_min;
// const int N = std::floor(L/dx);
//
//
// for (double x : points) //GPT loop, to check
// {
// x-= x_min;
// x = x - L * std::floor(x/L);
//
// int i = static_cast<int>(std::floor(x / dx));
//
// // safety: handle rare edge case due to floating precision
// if (i == N) i = 0;
//
// indices.push_back(i);
// }
// }
// case 1:
// {
// throw std::invalid_argument("Case for non uniform grid is not
// completed");
// }
// default:
// throw std::invalid_argument("Invalid grid_type argument");
//
// }
// return indices;
// }
inline std::vector<double> make_x_eval(size_t Nx) {
std::vector<double> x_eval(Nx);
for (size_t i = 0; i < Nx; ++i)
x_eval[i] = Parameters::X_DOMAIN_LEFT + i * Parameters::CALC_DX;
return x_eval;
}
inline void reset_x_eval(std::vector<double> &x_vals) {
const size_t Nx = x_vals.size();
for (size_t i = 0; i < Nx; ++i)
x_vals[i] = Parameters::X_DOMAIN_LEFT + i * Parameters::CALC_DX;
};
inline double f0(const double x, const double v,
const double eps = Parameters::EPS,
const double k = Parameters::WAVE_NR) {
const double prefactor =
Parameters::F0_FACTOR * (1.0 + eps * std::cos(k * x));
const double gaussian = v * v * std::exp(-0.5 * v * v);
return prefactor * gaussian;
}
// wrapper for eval_point() { VectorTools::point_values() }
inline std::vector<double> eval(std::vector<double> &X,
const PoissonProblem<1> &poisson,
const Vector<double> &solution) noexcept {
size_t x_size = X.size();
std::vector<double> evals(x_size);
std::vector<Point<1>> Points(x_size);
for (size_t i = 0; i < x_size; ++i) {
X[i] = X[i] - Parameters::X_DOMAIN_LEFT;
X[i] = X[i] - Parameters::LX * std::floor(X[i] * Parameters::LX_INV);
Points[i][0] = X[i];
}
return poisson.eval_vector_grad(solution, Points);
}
inline double integral_space_vector(const PoissonProblem<1> &poisson,
const Vector<double> &solution,
double dx = Parameters::PLOT_DX,
size_t Nx = Parameters::PLOT_NX) {
double integral = 0.0;
double xmin = Parameters::X_DOMAIN_LEFT;
std::vector<double> x_eval(Nx);
for (size_t i = 0; i < Nx; ++i)
x_eval[i] = xmin + i * dx;
std::vector<double> tmp = eval(x_eval, poisson, solution);
for (size_t i = 0; i < Nx; ++i)
integral += tmp[i];
return integral * dx;
};
inline double integral_space_vector_squared(const PoissonProblem<1> &poisson,
const Vector<double> &solution,
double dx = Parameters::PLOT_DX,
size_t Nx = Parameters::PLOT_NX) {
double integral = 0.0;
double xmin = Parameters::X_DOMAIN_LEFT;
std::vector<double> x_eval(Nx);
for (size_t i = 0; i < Nx; ++i)
x_eval[i] = xmin + i * dx;
std::vector<double> tmp = eval(x_eval, poisson, solution);
for (size_t i = 0; i < Nx; ++i)
integral += tmp[i] * tmp[i];
return integral * dx;
};
#endif