aboutsummaryrefslogtreecommitdiff
path: root/Source/Initialization/InjectorFlux.H
blob: adfe75b3ed2a5f1fd9f3d07c9eb8d7025493884e (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
135
136
137
138
139
140
141
142
143
144
145
146
/* Copyright 2023 Remi Lehe
 *
 * This file is part of WarpX.
 *
 * License: BSD-3-Clause-LBNL
 */
#ifndef INJECTOR_FLUX_H_
#define INJECTOR_FLUX_H_

#include "Utils/WarpXConst.H"

#include <AMReX.H>
#include <AMReX_Array.H>
#include <AMReX_GpuQualifiers.H>
#include <AMReX_Math.H>
#include <AMReX_Parser.H>
#include <AMReX_REAL.H>

#include <cmath>
#include <string>

// struct whose getFlux returns constant flux.
struct InjectorFluxConstant
{
    InjectorFluxConstant (amrex::Real a_flux) noexcept : m_flux(a_flux) {}

    AMREX_GPU_HOST_DEVICE
    amrex::Real
    getFlux (amrex::Real, amrex::Real, amrex::Real, amrex::Real) const noexcept
    {
        return m_flux;
    }

private:
    amrex::Real m_flux;
};

// struct whose getFlux returns local flux computed from parser.
struct InjectorFluxParser
{
    InjectorFluxParser (amrex::ParserExecutor<4> const& a_parser) noexcept
        : m_parser(a_parser) {}

    AMREX_GPU_HOST_DEVICE
    amrex::Real
    getFlux (amrex::Real x, amrex::Real y, amrex::Real z, amrex::Real t) const noexcept
    {
        return m_parser(x,y,z,t);
    }

    amrex::ParserExecutor<4> m_parser;
};

// Base struct for flux injector.
// InjectorFlux contains a union (called Object) that holds any one
// instance of:
// - InjectorFluxConstant  : to generate constant flux;
// - InjectorFluxParser    : to generate flux from parser;
// The choice is made at runtime, depending in the constructor called.
// This mimics virtual functions.
struct InjectorFlux
{
    // This constructor stores a InjectorFluxConstant in union object.
    InjectorFlux (InjectorFluxConstant* t, amrex::Real a_flux)
        : type(Type::constant),
          object(t,a_flux)
    { }

    // This constructor stores a InjectorFluxParser in union object.
    InjectorFlux (InjectorFluxParser* t, amrex::ParserExecutor<4> const& a_parser)
        : type(Type::parser),
          object(t,a_parser)
    { }

    // Explicitly prevent the compiler from generating copy constructors
    // and copy assignment operators.
    InjectorFlux (InjectorFlux const&) = delete;
    InjectorFlux (InjectorFlux&&) = delete;
    void operator= (InjectorFlux const&) = delete;
    void operator= (InjectorFlux &&) = delete;

    void clear ()
    {
        switch (type)
        {
        case Type::constant:
        case Type::parser:
        {
            break;
        }
        }
    }

    // call getFlux from the object stored in the union
    // (the union is called Object, and the instance is called object).
    AMREX_GPU_HOST_DEVICE
    amrex::Real
    getFlux (amrex::Real x, amrex::Real y, amrex::Real z, amrex::Real t) const noexcept
    {
        switch (type)
        {
        case Type::parser:
        {
            return object.parser.getFlux(x,y,z,t);
        }
        case Type::constant:
        {
            return object.constant.getFlux(x,y,z,t);
        }
        default:
        {
            amrex::Abort("InjectorFlux: unknown type");
            return 0.0;
        }
        }
    }

private:
    enum struct Type { constant, parser };
    Type type;

    // An instance of union Object constructs and stores any one of
    // the objects declared (constant or parser).
    union Object {
        Object (InjectorFluxConstant*, amrex::Real a_flux) noexcept
            : constant(a_flux) {}
        Object (InjectorFluxParser*, amrex::ParserExecutor<4> const& a_parser) noexcept
            : parser(a_parser) {}
        InjectorFluxConstant   constant;
        InjectorFluxParser     parser;
    };
    Object object;
};

// In order for InjectorFlux to be trivially copyable, its destructor
// must be trivial.  So we have to rely on a custom deleter for unique_ptr.
struct InjectorFluxDeleter {
    void operator () (InjectorFlux* p) const {
        if (p) {
            p->clear();
            delete p;
        }
    }
};

#endif