blob: 3a868838a10b84093516504d78cc88dba8e01748 (
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
|
#include "WarpXParser.H"
WarpXParser::WarpXParser (std::string const& func_body)
{
define(func_body);
}
void
WarpXParser::define (std::string const& func_body)
{
clear();
m_expression = func_body;
#ifdef _OPENMP
int nthreads = omp_get_max_threads();
#else
int nthreads = 1;
#endif
m_parser.resize(nthreads);
std::string f = m_expression + "\n";
m_parser[0] = wp_c_parser_new(f.c_str());
#ifdef _OPENMP
#pragma omp parallel
{
int tid = omp_get_thread_num();
if (tid > 0) {
m_parser[tid] = wp_parser_dup(m_parser[0]);
}
}
#endif
}
WarpXParser::~WarpXParser ()
{
clear();
}
void
WarpXParser::clear ()
{
if (!m_parser.empty())
{
#ifdef _OPENMP
#pragma omp parallel
{
int tid = omp_get_thread_num();
wp_parser_delete(m_parser[tid]);
}
#else
wp_parser_delete(m_parser[0]);
#endif
}
m_expression.clear();
m_parser.clear();
m_variables.clear();
}
void
WarpXParser::registerVariable (std::string const& name, double& var)
{
// We assume this is called inside OMP parallel region
#ifdef _OPENMP
const int tid = omp_get_thread_num();
#else
const int tid = 0;
#endif
wp_parser_regvar(m_parser[tid], name.c_str(), &var);
}
// This must be called outside OpenMP parallel region.
void
WarpXParser::registerVariables (std::vector<std::string> const& names)
{
#ifdef _OPENMP
const int nthreads = omp_get_max_threads();
#else
const int nthreads = 1;
#endif
m_variables.resize(nthreads);
const int nnames = names.size();
#ifdef _OPENMP
#pragma omp parallel for
#endif
for (int i = 0; i < nthreads; ++i) {
m_variables[i].resize(nnames);
for (int j = 0; j < nnames; ++i) {
wp_parser_regvar(m_parser[i], names[j].c_str(), &(m_variables[i][j]));
}
}
}
void
WarpXParser::setConstant (std::string const& name, double c)
{
// We don't know if this is inside OMP parallel region or not
#ifdef _OPENMP
bool in_parallel = omp_in_parallel();
#pragma omp parallel if (!in_parallel)
{
wp_parser_setconst(m_parser[omp_get_thread_num()], name.c_str(), c);
}
#else
wp_parser_setconst(m_parser[0], name.c_str(), c);
#endif
}
void
WarpXParser::print () const
{
#ifdef _OPENMP
#pragma omp critical(warpx_parser_pint)
wp_ast_print(m_parser[omp_get_thread_num()]->ast);
#else
wp_ast_print(m_parser[0]->ast);
#endif
}
std::string const&
WarpXParser::expr () const
{
return m_expression;
}
|