LCOV - code coverage report
Current view: top level - cell - ReactionEngine.hpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 10 11 90.9 %
Date: 2025-12-26 22:55:38 Functions: 2 2 100.0 %

          Line data    Source code
       1             : #ifndef REACTIONENGINE_HPP
       2             : #define REACTIONENGINE_HPP
       3             : 
       4             : #include "CollisionDetector.hpp"
       5             : #include "MathUtils.hpp"
       6             : 
       7             : #include <functional>
       8             : #include <optional>
       9             : #include <unordered_set>
      10             : 
      11             : namespace cell
      12             : {
      13             : 
      14             : class DiscType;
      15             : class Disc;
      16             : class ReactionTable;
      17             : 
      18             : using SingleLookupMap = DiscTypeMap<std::vector<Reaction>>;
      19             : using PairLookupMap = DiscTypePairMap<std::vector<Reaction>>;
      20             : 
      21             : class ReactionEngine
      22             : {
      23             : public:
      24             :     ReactionEngine(const DiscTypeRegistry& discTypeRegistry, const ReactionTable& reactionTable);
      25             : 
      26             :     /**
      27             :      * @brief Transformation reaction A -> B. Changes the type of the disc to a new one if a reaction occurs.
      28             :      */
      29             :     Disc transformationReaction(Disc* educt, DiscTypeID productID) const;
      30             : 
      31             :     /**
      32             :      * @brief Decomposition reaction A -> B + C.
      33             :      */
      34             :     std::pair<Disc, Disc> decompositionReaction(Disc* educt, DiscTypeID product1ID, DiscTypeID product2ID) const;
      35             : 
      36             :     /**
      37             :      * @brief Combination reaction A + B -> C. Destroys one of the 2 educt discs and changes the other if a reaction
      38             :      * occurs.
      39             :      */
      40             :     Disc combinationReaction(Disc* educt1, Disc* educt2, DiscTypeID productID) const;
      41             : 
      42             :     /**
      43             :      * @brief Exchange reaction A + B -> C + D. Just changes the disc types of the reacting discs.
      44             :      */
      45             :     std::pair<Disc, Disc> exchangeReaction(Disc* educt1, Disc* educt2, DiscTypeID product1ID,
      46             :                                            DiscTypeID product2ID) const;
      47             : 
      48             :     void applyUnimolecularReactions(Disc& disc, double dt, std::vector<Disc>& newDiscs) const;
      49             : 
      50             :     void applyBimolecularReactions(const std::vector<CollisionDetector::Collision>& collisions,
      51             :                                    std::vector<Disc>& newDiscs) const;
      52             : 
      53             : private:
      54             :     template <typename MapType, typename KeyType, typename Condition>
      55             :     const Reaction* selectReaction(const MapType& map, const KeyType& key, const Condition& condition) const;
      56             : 
      57             :     const Reaction* selectUnimolecularReaction(const DiscTypeID& key, double dt) const;
      58             :     const Reaction* selectBimolecularReaction(const std::pair<DiscTypeID, DiscTypeID>& key) const;
      59             :     void combineReactionsIntoSingleMaps(const ReactionTable& reactionTable);
      60             : 
      61             : private:
      62             :     const DiscTypeRegistry& discTypeRegistry_;
      63             :     SingleLookupMap unimolecularReactions_;
      64             :     PairLookupMap bimolecularReactions_;
      65             : };
      66             : 
      67             : template <typename MapType, typename KeyType, typename Condition>
      68          33 : inline const Reaction* ReactionEngine::selectReaction(const MapType& map, const KeyType& key,
      69             :                                                       const Condition& condition) const
      70             : {
      71          33 :     auto iter = map.find(key);
      72          33 :     if (iter == map.end())
      73          25 :         return nullptr;
      74             : 
      75           8 :     const auto& reactions = iter->second;
      76             : 
      77             :     // ReactionTable never constructs empty vectors, so reaction.size() is always > 0
      78           8 :     auto start = mathutils::getRandomNumber<std::size_t>(0, reactions.size() - 1);
      79             : 
      80           8 :     for (std::size_t i = 0; i < reactions.size(); ++i)
      81             :     {
      82           8 :         const auto& reaction = reactions[(start + i) % reactions.size()];
      83           8 :         if (condition(reaction))
      84           8 :             return &reaction;
      85             :     }
      86             : 
      87           0 :     return nullptr;
      88             : }
      89             : 
      90             : } // namespace cell
      91             : 
      92             : #endif /* REACTIONENGINE_HPP */

Generated by: LCOV version 1.14