Vlasiator ebf0dd394 on dev (v5.4.0 + 1054 commits)
Loading...
Searching...
No Matches
cpu_1d_column_interpolations.hpp
Go to the documentation of this file.
1/*
2This file is part of Vlasiator.
3Copyright 2013, 2014 Finnish Meteorological Institute
4
5*/
6
7#ifndef CPU_1D_COLUMN_INTERP_H
8#define CPU_1D_COLUMN_INTERP_H
9
10#include "algorithm"
11#include "cmath"
13
14using namespace std;
15
16
17/*Compute all face values. For cell k (globla index), its left face
18 * value is in fv_l[k] and right value in fv_r[k]. Based on explicit
19 * h6 estimate*/
20inline void compute_h6_face_values(Real *values, uint n_cblocks, Real *fv_l, Real *fv_r){
21
22 /*we loop up to one extra cell. There is extra space in fv for the extra left value*/
23 for (int k = 0; k < n_cblocks * WID + 1; k++){
24 /*compute left values*/
25 fv_l[k] = 1.0/60.0 * (values[k - 3 + WID] - 8.0 * values[k - 2 + WID] + 37.0 * values[k - 1 + WID] +
26 37.0 * values[k + WID] - 8.0 * values[k + 1 + WID] + values[k + 2 + WID]);
27 /*set right value*/
28 if(k>0)
29 fv_r[k-1] = fv_l[k];
30 }
31}
32
33
34inline void filter_extrema(Real *values, uint n_cblocks, Real *fv_l, Real *fv_r){
35 for (int k = 0; k < n_cblocks * WID; k++){
36 //Coella1984 eq. 1.10, detect extrema and make algorithm constant if it is
37 Real extrema_check = ((fv_r[k] - values[k + WID]) * (values[k + WID] - fv_l[k]));
38 fv_l[k] = extrema_check < 0 ? values[k + WID]: fv_l[k];
39 fv_r[k] = extrema_check < 0 ? values[k + WID]: fv_r[k];
40 }
41}
42
43/*Filter according to Eq. 19 in White et al.*/
44inline void filter_boundedness(Real *values, uint n_cblocks, Real *fv_l, Real *fv_r){
45 /*First Eq. 19 & 20*/
46 for (int k = 0; k < n_cblocks * WID; k++){
47 bool do_fix_bounds =
48 (values[k - 1 + WID] - fv_l[k]) * (fv_l[k] - values[k + WID]) < 0 ||
49 (values[k + 1 + WID] - fv_r[k]) * (fv_r[k] - values[k + WID]) < 0;
50 if(do_fix_bounds) {
51 Real slope_abs,slope_sign;
52 slope_limiter(values[k -1 + WID], values[k + WID], values[k + 1 + WID], slope_abs, slope_sign);
53 //detect and fix boundedness, as in WHITE 2008
54 fv_l[k] = (values[k -1 + WID] - fv_l[k]) * (fv_l[k] - values[k + WID]) < 0 ?
55 values[k + WID] - slope_sign * min( (Real)0.5 * slope_abs, abs(fv_l[k] - values[k + WID])) :
56 fv_l[k];
57 fv_r[k] = (values[k + 1 + WID] - fv_r[k]) * (fv_r[k] - values[k + WID]) < 0 ?
58 values[k + WID] + slope_sign * min( (Real)0.5 * slope_abs, abs(fv_r[k] - values[k + WID])) :
59 fv_r[k];
60 }
61 }
62}
63
64
71
72inline void compute_plm_coeff_explicit_column(Real *values, uint n_cblocks, Real a[][RECONSTRUCTION_ORDER + 1]){
73 for (uint k = 0; k < n_cblocks * WID; k++){
74 const Real d_cv=slope_limiter(values[k - 1 + WID], values[k + WID], values[k + 1 + WID]);
75 a[k][0] = values[k + WID] - d_cv * 0.5;
76 a[k][1] = d_cv * 0.5;
77 }
78}
79
80/*
81 Compute parabolic reconstruction with an explicit scheme
82
83 Note that value array starts with an empty block, thus values[k + WID]
84 corresponds to the current (centered) cell.
85*/
86
87inline void compute_ppm_coeff_explicit_column(Real *values, uint n_cblocks, Real a[][RECONSTRUCTION_ORDER + 1]){
88 Real p_face;
89 Real m_face;
90 Real fv_l[MAX_BLOCKS_PER_DIM * WID + 1]; /*left face value, extra space for ease of implementation*/
91 Real fv_r[MAX_BLOCKS_PER_DIM * WID + 1]; /*right face value*/
92
93 compute_h6_face_values(values,n_cblocks,fv_l, fv_r);
94 filter_boundedness(values,n_cblocks,fv_l, fv_r);
95 filter_extrema(values,n_cblocks,fv_l, fv_r);
96
97 for (uint k = 0; k < n_cblocks * WID; k++){
98 m_face = fv_l[k];
99 p_face = fv_r[k];
100
101 //Coella et al, check for monotonicity
102 m_face = (p_face - m_face) * (values[k + WID] - 0.5 * (m_face + p_face)) > (p_face - m_face)*(p_face - m_face) / 6.0 ?
103 3 * values[k + WID] - 2 * p_face : m_face;
104 p_face = -(p_face - m_face) * (p_face - m_face) / 6.0 > (p_face - m_face) * (values[k + WID] - 0.5 * (m_face + p_face)) ?
105 3 * values[k + WID] - 2 * m_face : p_face;
106
107 //Fit a second order polynomial for reconstruction see, e.g., White
108 //2008 (PQM article) (note additional integration factors built in,
109 //contrary to White (2008) eq. 4
110 a[k][0] = m_face;
111 a[k][1] = 3.0 * values[k + WID] - 2.0 * m_face - p_face;
112 a[k][2] = (m_face + p_face - 2.0 * values[k + WID]);
113 }
114}
115
116
117
118#endif
#define WID
Definition common.h:514
#define MAX_BLOCKS_PER_DIM
Definition common.h:73
void compute_h6_face_values(Real *values, uint n_cblocks, Real *fv_l, Real *fv_r)
void compute_plm_coeff_explicit_column(Real *values, uint n_cblocks, Real a[][RECONSTRUCTION_ORDER+1])
void compute_ppm_coeff_explicit_column(Real *values, uint n_cblocks, Real a[][RECONSTRUCTION_ORDER+1])
void filter_boundedness(Real *values, uint n_cblocks, Real *fv_l, Real *fv_r)
void filter_extrema(Real *values, uint n_cblocks, Real *fv_l, Real *fv_r)
float Real
Definition definitions.h:41
const int k
Real slope_limiter(const Real &l, const Real &m, const Real &r)
static ARCH_HOSTDEV VecSimple< T > min(VecSimple< T > const &l, VecSimple< T > const &r)
static ARCH_HOSTDEV VecSimple< T > abs(const VecSimple< T > &l)