aboutsummaryrefslogtreecommitdiff
path: root/Source/FieldSolver/FiniteDifferenceSolver/FiniteDifferenceAlgorithms/NodalAlgorithm.H
blob: c040a7846aac5de10372f1834875506fd417b2a9 (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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/* Copyright 2020 Remi Lehe
 *
 * This file is part of WarpX.
 *
 * License: BSD-3-Clause-LBNL
 */

#ifndef WARPX_FINITE_DIFFERENCE_ALGORITHM_NODAL_H_
#define WARPX_FINITE_DIFFERENCE_ALGORITHM_NODAL_H_

#include <AMReX_REAL.H>
#include <AMReX_Array4.H>
#include <AMReX_Gpu.H>

struct NodalAlgorithm {

    static void InitializeStencilCoefficients(
        std::array<amrex::Real,3>& cell_size,
        amrex::Gpu::ManagedVector<amrex::Real>& stencil_coefs_x,
        amrex::Gpu::ManagedVector<amrex::Real>& stencil_coefs_y,
        amrex::Gpu::ManagedVector<amrex::Real>& stencil_coefs_z ) {

        // Store the inverse cell size along each direction in the coefficients
        stencil_coefs_x.resize(1);
        stencil_coefs_x[0] = 1./cell_size[0];
        stencil_coefs_y.resize(1);
        stencil_coefs_y[0] = 1./cell_size[1];
        stencil_coefs_z.resize(1);
        stencil_coefs_z[0] = 1./cell_size[2];
    }

    /**
    /* Perform derivative along x
    /* (For a solver on a staggered grid, `UpwardDx` and `DownwardDx` take into
    /* account the staggering; but for `NodalAlgorithm`, they are equivalent) */
    AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
    static amrex::Real UpwardDx(
        amrex::Array4<amrex::Real> const& F,
        amrex::Real const* coefs_x, int const n_coefs_x,
        int const i, int const j, int const k ) {

        amrex::Real const inv_dx = coefs_x[0];
        return 0.5*inv_dx*( F(i+1,j,k) - F(i-1,j,k) );
    };

    /**
    /* Perform derivative along x
    /* (For a solver on a staggered grid, `UpwardDx` and `DownwardDx` take into
    /* account the staggering; but for `NodalAlgorithm`, they are equivalent) */
    AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
    static amrex::Real Downwardx(
        amrex::Array4<amrex::Real> const& F,
        amrex::Real const* coefs_x, int const n_coefs_x,
        int const i, int const j, int const k ) {

        amrex::Real const inv_dx = coefs_x[0];
        return 0.5*inv_dx*( F(i+1,j,k) - F(i-1,j,k) );
    };

    /**
    /* Perform derivative along y
    /* (For a solver on a staggered grid, `UpwardDy` and `DownwardDy` take into
    /* account the staggering; but for `NodalAlgorithm`, they are equivalent) */
    AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
    static amrex::Real UpwardDy(
        amrex::Array4<amrex::Real> const& F,
        amrex::Real const* coefs_y, int const n_coefs_y,
        int const i, int const j, int const k ) {

#        if defined WARPX_DIM_3D
            amrex::Real const inv_dy = coefs_y[0];
            return 0.5*inv_dy*( F(i,j+1,k) - F(i,j-1,k) );
#        elif (defined WARPX_DIM_XZ)
            return 0; // 2D Cartesian: derivative along y is 0
#        endif
    };

    /**
    /* Perform derivative along y
    /* (For a solver on a staggered grid, `UpwardDy` and `DownwardDy` take into
    /* account the staggering; but for `NodalAlgorithm`, they are equivalent) */
    AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
    static amrex::Real Downwardy(
        amrex::Array4<amrex::Real> const& F,
        amrex::Real const* coefs_y, int const n_coefs_y,
        int const i, int const j, int const k ) {

#        if defined WARPX_DIM_3D
            amrex::Real const inv_dy = coefs_y[0];
            return 0.5*inv_dy*( F(i,j+1,k) - F(i,j-1,k) );
#        elif (defined WARPX_DIM_XZ)
            return 0; // 2D Cartesian: derivative along y is 0
#        endif
    };

    /**
    /* Perform derivative along z
    /* (For a solver on a staggered grid, `UpwardDz` and `DownwardDz` take into
    /* account the staggering; but for `NodalAlgorithm`, they are equivalent) */
    AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
    static amrex::Real UpwardDz(
        amrex::Array4<amrex::Real> const& F,
        amrex::Real const* coefs_z, int const n_coefs_z,
        int const i, int const j, int const k ) {

        amrex::Real const inv_dz = coefs_z[0];
#        if defined WARPX_DIM_3D
            return 0.5*inv_dz*( F(i,j,k+1) - F(i,j,k-1) );
#        elif (defined WARPX_DIM_XZ)
            return 0.5*inv_dz*( F(i,j+1,k) - F(i,j-1,k) );
#        endif
    };

    /**
    /* Perform derivative along z
    /* (For a solver on a staggered grid, `UpwardDz` and `DownwardDz` take into
    /* account the staggering; but for `NodalAlgorithm`, they are equivalent) */
    AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
    static amrex::Real Downwardz(
        amrex::Array4<amrex::Real> const& F,
        amrex::Real const* coefs_z, int const n_coefs_z,
        int const i, int const j, int const k ) {

        amrex::Real const inv_dz = coefs_z[0];
#        if defined WARPX_DIM_3D
            return 0.5*inv_dz*( F(i,j,k+1) - F(i,j,k-1) );
#        elif (defined WARPX_DIM_XZ)
            return 0.5*inv_dz*( F(i,j+1,k) - F(i,j-1,k) );
#        endif
    };

};

#endif // WARPX_FINITE_DIFFERENCE_ALGORITHM_NODAL_H_