Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 09:07:50

0001 //------------------------------- -*- C++ -*- -------------------------------//
0002 // Copyright Celeritas contributors: see top-level COPYRIGHT file for details
0003 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
0004 //---------------------------------------------------------------------------//
0005 //! \file orange/univ/detail/LogicEvaluator.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include <type_traits>
0010 
0011 #include "corecel/Assert.hh"
0012 #include "corecel/cont/Span.hh"
0013 #include "corecel/data/LdgIterator.hh"
0014 #include "orange/OrangeTypes.hh"
0015 #include "orange/SenseUtils.hh"
0016 
0017 #include "LogicStack.hh"
0018 
0019 namespace celeritas
0020 {
0021 namespace detail
0022 {
0023 //---------------------------------------------------------------------------//
0024 /*!
0025  * Evaluate a logical expression applied to a vector of senses.
0026  */
0027 class LogicEvaluator
0028 {
0029   public:
0030     //@{
0031     //! \name Type aliases
0032     using SpanConstLogic = LdgSpan<logic_int const>;
0033     using SpanConstSense = Span<SenseValue const>;
0034     //@}
0035 
0036   public:
0037     // Construct with a view to some logic definition
0038     explicit CELER_FORCEINLINE_FUNCTION LogicEvaluator(SpanConstLogic logic);
0039 
0040     // Evaluate a logical expression, substituting bools from the vector
0041     inline CELER_FUNCTION bool operator()(SpanConstSense values) const;
0042 
0043     // Evaluate a logical expression, with on-the-fly sense evaluation
0044     template<class F, std::enable_if_t<std::is_invocable_v<F, FaceId>, bool> = true>
0045     inline CELER_FUNCTION bool operator()(F&& eval_sense) const;
0046 
0047   private:
0048     //// DATA ////
0049 
0050     SpanConstLogic logic_;
0051 };
0052 
0053 //---------------------------------------------------------------------------//
0054 /*!
0055  * Construct with a view to some logic definition.
0056  */
0057 CELER_FUNCTION LogicEvaluator::LogicEvaluator(SpanConstLogic logic)
0058     : logic_(logic)
0059 {
0060     CELER_EXPECT(!logic_.empty());
0061 }
0062 
0063 //---------------------------------------------------------------------------//
0064 /*!
0065  * Evaluate a logical expression, substituting bools from the sense view.
0066  */
0067 CELER_FUNCTION bool LogicEvaluator::operator()(SpanConstSense values) const
0068 {
0069     auto calc_sense
0070         = [&](FaceId face_id) -> Sense { return values[face_id.get()]; };
0071     return (*this)(calc_sense);
0072 }
0073 
0074 //---------------------------------------------------------------------------//
0075 /*!
0076  * Evaluate a logical expression, with on-the-fly sense evaluation.
0077  */
0078 template<class F, std::enable_if_t<std::is_invocable_v<F, FaceId>, bool>>
0079 CELER_FUNCTION bool LogicEvaluator::operator()(F&& eval_sense) const
0080 {
0081     LogicStack stack;
0082 
0083     for (logic_int lgc : logic_)
0084     {
0085         if (!logic::is_operator_token(lgc))
0086         {
0087             // Push a boolean from the senses onto the stack
0088             stack.push(static_cast<bool>(eval_sense(FaceId{lgc})));
0089             continue;
0090         }
0091 
0092         // Apply logic operator
0093         switch (lgc)
0094         {
0095                 // clang-format off
0096             case logic::ltrue: stack.push(true);  break;
0097             case logic::lor:   stack.apply_or();  break;
0098             case logic::land:  stack.apply_and(); break;
0099             case logic::lnot:  stack.apply_not(); break;
0100             default:           CELER_ASSERT_UNREACHABLE();
0101         }
0102         // clang-format on
0103     }
0104     CELER_ENSURE(stack.size() == 1);
0105     return stack.top();
0106 }
0107 
0108 //---------------------------------------------------------------------------//
0109 }  // namespace detail
0110 }  // namespace celeritas