/* Copyright 2019 Weiqun Zhang * * This file is part of WarpX. * * License: BSD-3-Clause-LBNL */ #ifndef WARPX_PARSER_H_ #define WARPX_PARSER_H_ #include #include #include #include #include #include "wp_parser_c.h" #include "wp_parser_y.h" #ifdef _OPENMP #include #endif template class GpuParser; class WarpXParser { public: WarpXParser (std::string const& func_body); WarpXParser () = default; ~WarpXParser (); void define (std::string const& func_body); void setConstant (std::string const& name, amrex::Real c); // // Option 1: Register every variable to an address provided. // Assign values to external variables. // Call eval(). void registerVariable (std::string const& name, amrex::Real& var); // inline amrex::Real eval () const noexcept; // // Option 2: Register all variables at once. Parser will create // variables internally. // Call eval(...) with variable values. void registerVariables (std::vector const& names); // template inline amrex::Real eval (T x, Ts... yz) const noexcept; void print () const; std::string const& expr () const; std::set symbols () const; template friend class GpuParser; private: void clear (); template inline void unpack (amrex::Real* p, T x) const noexcept; template inline void unpack (amrex::Real* p, T x, Ts... yz) const noexcept; std::string m_expression; #ifdef _OPENMP std::vector m_parser; mutable std::vector > m_variables; mutable std::vector > m_varnames; #else struct wp_parser* m_parser = nullptr; mutable std::array m_variables; mutable std::vector m_varnames; #endif }; inline amrex::Real WarpXParser::eval () const noexcept { #ifdef _OPENMP return wp_ast_eval(m_parser[omp_get_thread_num()]->ast,nullptr); #else return wp_ast_eval(m_parser->ast,nullptr); #endif } template inline amrex::Real WarpXParser::eval (T x, Ts... yz) const noexcept { #ifdef _OPENMP unpack(m_variables[omp_get_thread_num()].data(), x, yz...); #else unpack(m_variables.data(), x, yz...); #endif return eval(); } template inline void WarpXParser::unpack (amrex::Real* p, T x) const noexcept { *p = x; } template inline void WarpXParser::unpack (amrex::Real* p, T x, Ts... yz) const noexcept { *p++ = x; unpack(p, yz...); } #endif