aboutsummaryrefslogtreecommitdiff
path: root/Source/Filter/NCIGodfreyFilter.cpp
blob: 25b5e67fd5d2e2790474f302387b5dddb078bba7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <WarpX.H>
#include <NCIGodfreyFilter.H>
#include <NCIGodfreyTables.H>

#ifdef _OPENMP
#include <omp.h>
#endif

using namespace amrex;

NCIGodfreyFilter::NCIGodfreyFilter(godfrey_coeff_set coeff_set_, amrex::Real cdtodz_, amrex::Real l_lower_order_in_v_){
    // Store parameters into class data members
    coeff_set = coeff_set_;
    cdtodz = cdtodz_;
    l_lower_order_in_v = l_lower_order_in_v_;
    // NCI Godfrey filter has fixed size, and is applied along z only.
#if (AMREX_SPACEDIM == 3)
    stencil_length_each_dir = {1,1,5};
    slen = {1,1,5};
#else
    stencil_length_each_dir = {1,5};
    slen = {1,5,1};
#endif
}

void NCIGodfreyFilter::ComputeStencils(){
    AMREX_ALWAYS_ASSERT_WITH_MESSAGE(
#if ( AMREX_SPACEDIM == 3 )
        slen.z==5,
#else
        slen.y==5,
#endif
        "ERROR: NCI filter requires 5 points in z");
    AMREX_ALWAYS_ASSERT_WITH_MESSAGE(l_lower_order_in_v==1,
        "ERROR: NCI corrector requires l_lower_order_in_v=1, i.e., Galerkin scheme");

    // Interpolate coefficients from the table, and store into prestencil.
    int index = tab_length*cdtodz;
    index = min(index, tab_length-2);
    index = max(index, 0);
    Real weight_right = cdtodz - index/tab_length;
    Real prestencil[4];
    for(int i=0; i<tab_width; i++){
        if        (coeff_set == godfrey_coeff_set::Ex_Ey_Bz) {
            prestencil[i] = (1-weight_right)*table_nci_godfrey_Ex_Ey_Bz[index  ][i] +
                                weight_right*table_nci_godfrey_Ex_Ey_Bz[index+1][i];
        } else if (coeff_set == godfrey_coeff_set::Bx_By_Ez) {
            prestencil[i] = (1-weight_right)*table_nci_godfrey_Bx_By_Ez[index  ][i] +
                                weight_right*table_nci_godfrey_Bx_By_Ez[index+1][i];
        }
    }

    // Compute stencil_z
    stencil_z.resize( 5 );
    stencil_z[0] =  (256 + 128*prestencil[0] + 96*prestencil[1] + 80*prestencil[2] + 70*prestencil[3]) / 256;
    stencil_z[1] = -(       64*prestencil[0] + 64*prestencil[1] + 60*prestencil[2] + 56*prestencil[3]) / 256;
    stencil_z[2] =  (                          16*prestencil[1] + 24*prestencil[2] + 28*prestencil[3]) / 256;
    stencil_z[3] = -(                                              4*prestencil[2] +  8*prestencil[3]) / 256;
    stencil_z[4] =  (                                                                 1*prestencil[3]) / 256;

    // Compute stencil_x and stencil_y (no filter in these directions,
    // so only 1 coeff, equal to 1)
    stencil_x.resize(1);
    stencil_x[0] = 1.;
#if (AMREX_SPACEDIM == 3)
    stencil_y.resize(1);
    stencil_y[0] = 1.;
#endif

    // Due to the way Filter::DoFilter() is written,
    // coefficient 0 has to be /2
    stencil_x[0] /= 2.;
#if (AMREX_SPACEDIM == 3)
    stencil_y[0] /= 2.;
#endif
    stencil_z[0] /= 2.;

}