Xyst test code coverage report
Current view: top level - Inciter/AMR - edge_store.hpp (source / functions) Coverage Total Hit
Commit: 1fb74642dd9d7732b67f32dec2f2762e238d3fa7 Lines: 88.5 % 26 23
Test Date: 2025-08-13 22:18:46 Functions: 100.0 % 3 3
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 31.2 % 16 5

             Branch data     Line data    Source code
       1                 :             : #ifndef AMR_edge_store_h
       2                 :             : #define AMR_edge_store_h
       3                 :             : 
       4                 :             : #include <cassert>
       5                 :             : 
       6                 :             : #include "Loggers.hpp"
       7                 :             : #include "AMR/AMR_types.hpp"
       8                 :             : 
       9                 :             : namespace AMR {
      10                 :             : 
      11                 :             :     class edge_store_t {
      12                 :             :         public:
      13                 :             :             // TODO: convert this to an unordered map with a custom hash (can lift from Xyst)
      14                 :             :             edges_t edges;
      15                 :             : 
      16                 :             :             // Node connectivity does this any way, but in a slightly less efficient way
      17                 :             :             // Maps the edge to the child node which splits it
      18                 :             :                 // This was added retrospectivley to support the operation "for
      19                 :             :                 // edge formed of initial nodes {A,B}, what node(s) were added
      20                 :             :                 // between them"
      21                 :             :                 // NOTE: At some point, this could probably be deleted..
      22                 :             :                 // NOTE: This is only mainted by split.
      23                 :             :             //std::map<edge_t, size_t> children;
      24                 :             : 
      25                 :             :             size_t size()
      26                 :             :             {
      27                 :             :                 return edges.size();
      28                 :             :             }
      29                 :             : 
      30                 :             :             /**
      31                 :             :              * @brief Function to create new edge between two nodes with an
      32                 :             :              * intermediate. Given nodes A, B, and AB makes edge A->AB and AB->B
      33                 :             :              *
      34                 :             :              * @param A First end node
      35                 :             :              * @param B Second end node
      36                 :             :              * @param AB Intermediate node
      37                 :             :              * @param lc Lock case for the new edges
      38                 :             :              */
      39                 :       83956 :             void split(size_t A, size_t B, size_t AB, Edge_Lock_Case lc)
      40                 :             :             {
      41                 :             :                 trace_out << "Splitting with lock case " << lc << std::endl;
      42                 :             :                 generate(A, AB, lc);
      43                 :             :                 generate(B, AB, lc);
      44                 :             : 
      45                 :             :                 //children.insert( std::pair<edge_t, size_t>(edge_t(A,B), AB));
      46                 :             :                 // Generate pertinent keys
      47                 :             :                 //edge_t keyAB = nodes_to_key(A, B);
      48                 :             : 
      49                 :             :                 // NOTE: This isn't explicitly needed in the paper, and may be
      50                 :             :                     // implicitly dealt with somewhere?
      51                 :             :                 //mark_edge_for_refinement(keyAB);
      52                 :       83956 :             }
      53                 :             : 
      54                 :             :             /**
      55                 :             :              * @brief Given nodes A and B, generate an edge between them
      56                 :             :              *
      57                 :             :              * @param A First node
      58                 :             :              * @param B Second node
      59                 :             :              * @param lc Lock case for new edge
      60                 :             :              */
      61                 :             :             void generate(size_t A, size_t B, Edge_Lock_Case lc)
      62                 :             :             {
      63                 :             :                 if ((A != 0) && (B != 0)) {
      64                 :             :                     trace_out << "A " << A << " B " << B << std::endl;
      65                 :             :                     assert(A != B);
      66                 :             :                 }
      67                 :             : 
      68                 :             :                 // Generate key
      69                 :             :                 edge_t keyAB = nodes_to_key(A, B);
      70                 :             :                 //Create refined edge
      71                 :             :                 Edge_Refinement edgeAB = Edge_Refinement(A, B, false, false, lc);
      72                 :             :                 // Add edge to store
      73                 :             :                 add(keyAB, edgeAB);
      74                 :             :             }
      75                 :             : 
      76                 :             :             bool exists(edge_t key) const
      77                 :             :             {
      78         [ -  + ]:        5784 :                 if (edges.find(key) != edges.end())
      79                 :             :                 {
      80                 :             :                     return true;
      81                 :             :                 }
      82                 :             :                 return false;
      83                 :             :             }
      84                 :             : 
      85                 :             :             /**
      86                 :             :              * @brief Function to retrieve an edge from the edge store
      87                 :             :              *
      88                 :             :              * @param key Key of the edge to get
      89                 :             :              *
      90                 :             :              * @return A reference to the fetched edge
      91                 :             :              */
      92                 :     7391701 :             Edge_Refinement& get(edge_t key)
      93                 :             :             {
      94                 :             :                 //trace_out << "get edge " << key << std::endl;
      95                 :             :                 // cppcheck-suppress assertWithSideEffect
      96                 :     7391701 :                 if (!exists(key)) trace_out << "key not found " << key.first()
      97                 :             :                   << " - " << key.second() << std::endl;
      98                 :             :                 assert( exists(key) );
      99                 :     7391701 :                 return edges[key];
     100                 :             :             }
     101                 :             : 
     102                 :             :             Edge_Lock_Case lock_case(const edge_t& key)
     103                 :             :             {
     104 [ -  - ][ -  - ]:        1536 :                 return get(key).lock_case;
         [ +  - ][ -  + ]
     105                 :             :             }
     106                 :             : 
     107                 :             :             void erase(edge_t key)
     108                 :             :             {
     109                 :             :                 trace_out << "Deref removing edge: " << key.first() << " - "
     110                 :             :                   << key.second() << std::endl;
     111                 :             :                 edges.erase(key);
     112                 :             :             }
     113                 :             : 
     114                 :             :             /**
     115                 :             :              * @brief Function to add edge to edge store
     116                 :             :              *
     117                 :             :              * @param key The key for the given edge
     118                 :             :              * @param e The edge data
     119                 :             :              *
     120                 :             :              * Note: This tolerate the addition of duplicate edges
     121                 :             :              */
     122                 :             :             void add(edge_t key, Edge_Refinement e)
     123                 :             :             {
     124                 :             :                 // Add edge if it doesn't exist (default behavior of insert)
     125                 :     6630257 :                 edges.insert( std::pair<edge_t, Edge_Refinement>(key, e));
     126                 :             : 
     127                 :             :                 // TODO: It may be worth adding a check here to ensure if we're
     128                 :             :                 // trying to add a new edge that exists it should contain the
     129                 :             :                 // same data
     130                 :             :             }
     131                 :             : 
     132                 :             :             static edge_t nodes_to_key(size_t A, size_t B)
     133                 :             :             {
     134                 :             :                 return edge_t(A,B);
     135                 :             :             }
     136                 :             : 
     137                 :             :             /**
     138                 :             :              * @brief Function to build a  string key from two node ids
     139                 :             :              * NOTE: Regardless of order of arguments, the same key will be generated
     140                 :             :              */
     141                 :             :             //static std::string nodes_to_key(size_t A, size_t B)
     142                 :             :             //{
     143                 :             :                 //return std::to_string(std::min(A,B)) + KEY_DELIM + std::to_string(std::max(A,B));
     144                 :             :             //}
     145                 :             : 
     146                 :             :             /**
     147                 :             :              * @brief function to take the nodes representing a face
     148                 :             :              * and to build the possible edges based on that
     149                 :             :              *
     150                 :             :              * For a given face {ABC}, generate the edge pairs {AB, AC, BC}
     151                 :             :              *
     152                 :             :              * @param face_ids The ids of the face to generate this for
     153                 :             :              *
     154                 :             :              * @return A (partially filled) list of all edges present on the
     155                 :             :              * face
     156                 :             :              */
     157                 :             :             // FIXME: Is it OK that it leaves some of the array blank?
     158                 :             :             static edge_list_t generate_keys_from_face_ids(face_ids_t face_ids)
     159                 :             :             {
     160                 :             :                 edge_list_t key_list;
     161                 :             :                 size_t A = face_ids[0];
     162                 :             :                 size_t B = face_ids[1];
     163                 :             :                 size_t C = face_ids[2];
     164                 :             : 
     165                 :             :                 edge_t key = nodes_to_key(A,B);
     166                 :        3135 :                 key_list[0] = key; // TODO: Is it OK to use copy assignment here?
     167                 :             : 
     168                 :             :                 key = nodes_to_key(A,C);
     169                 :        3135 :                 key_list[1] = key;
     170                 :             : 
     171                 :             :                 key = nodes_to_key(B,C);
     172                 :        3135 :                 key_list[2] = key;
     173                 :             : 
     174                 :             :                 return key_list;
     175                 :             :             }
     176                 :             : 
     177                 :             :             /**
     178                 :             :              * @brief function to take a list of edge and mark them all
     179                 :             :              * as needing to be refined
     180                 :             :              *
     181                 :             :              * @param ids List of ids to mark for refinement
     182                 :             :              */
     183                 :             :             void mark_edges_for_refinement(std::vector<node_pair_t> ids) {
     184                 :             :                 for (const auto& id : ids)
     185                 :             :             {
     186                 :             :                     edge_t key = nodes_to_key(id[0], id[1]);
     187                 :             : 
     188                 :             :                     mark_for_refinement(key);
     189                 :             :                     trace_out << get(key).needs_refining << std::endl;
     190                 :             :                 }
     191                 :             :             }
     192                 :             : 
     193                 :             : 
     194                 :             :             /**
     195                 :             :              * @brief function to mark a single edge as needing
     196                 :             :              * refinement (provides a nice abstraction from messing with the
     197                 :             :              * struct directly).
     198                 :             :              *
     199                 :             :              * @param key The edge key to mark as refinement
     200                 :             :              */
     201                 :             :             void mark_for_refinement(const edge_t& key)
     202                 :             :             {
     203                 :             :                 // cppcheck-suppress assertWithSideEffect
     204                 :             :                 assert( exists(key) );
     205         [ -  - ]:      298815 :                 get(key).needs_refining = 1;
     206                 :           0 :             }
     207                 :             : 
     208                 :             :             /**
     209                 :             :              * @brief function to take a list of edge and mark them all
     210                 :             :              * as needing to be refined as a part of the 8:4 derefinement
     211                 :             :              *
     212                 :             :              * @param ids List of ids to mark for deref-refinement
     213                 :             :              */
     214                 :          16 :             void mark_edges_for_deref_ref(std::vector<node_pair_t> ids)
     215                 :             :             {
     216         [ +  + ]:          64 :               for (const auto& id : ids)
     217                 :             :                 {
     218                 :          48 :                   edge_t key = nodes_to_key(id[0], id[1]);
     219                 :             : 
     220                 :             :                   // cppcheck-suppress assertWithSideEffect
     221                 :             :                   assert( exists(key) );
     222                 :             :                   // value of 2 for needs_refining indicates part of derefine
     223                 :          48 :                   get(key).needs_refining = 2;
     224                 :             : 
     225                 :             :                   trace_out << "edge: " << key.get_data()[0] << "-"
     226                 :             :                     << key.get_data()[1] << " deref-ref: "
     227                 :             :                     << get(key).needs_refining << std::endl;
     228                 :             :                 }
     229                 :          16 :             }
     230                 :             : 
     231                 :             :             /**
     232                 :             :              * @brief Function to unmark and edge as needing refinement
     233                 :             :              *
     234                 :             :              * @param key The key representing the edge to unmark
     235                 :             :              */
     236                 :             :             void unmark_for_refinement(const edge_t& key)
     237                 :             :             {
     238                 :             :                 // cppcheck-suppress assertWithSideEffect
     239                 :             :                 assert( exists(key) );
     240         [ -  - ]:           0 :                 get(key).needs_refining = 0;
     241                 :           0 :             }
     242                 :             : 
     243                 :             :             /**
     244                 :             :              * @brief For a given list of node pairs, mark the edge as needing
     245                 :             :              * to be de-refined
     246                 :             :              *
     247                 :             :              * @param ids a vector of pairs to mark for derefinement
     248                 :             :              */
     249                 :             :             void mark_edges_for_derefinement(std::vector<node_pair_t> ids) {
     250                 :             :                 for (const auto& id : ids)
     251                 :             :                 {
     252                 :             :                     edge_t key = nodes_to_key(id[0], id[1]);
     253                 :             : 
     254                 :             :                     mark_edge_for_derefinement(key);
     255                 :             :                 }
     256                 :             :             }
     257                 :             :             void mark_edge_for_derefinement(const edge_t& key) {
     258                 :             :                     get(key).needs_derefining = true;
     259                 :             :             }
     260                 :             : 
     261                 :             : 
     262                 :             :             /**
     263                 :             :              * @brief Function to generate a list of edge keys from a tet
     264                 :             :              *
     265                 :             :              * @param tet The tet to generate edge pairs for
     266                 :             :              *
     267                 :             :              * @return A list (array) of edge keys which can be separated out to
     268                 :             :              * name the two composing node ids
     269                 :             :              */
     270                 :             :             edge_list_t generate_keys(tet_t tet)
     271                 :             :             {
     272                 :             :                 // FIXME : Generate these with a (2d) loop and not hard code them?
     273                 :             :                 edge_list_t key_list;
     274                 :             : 
     275                 :             :                 size_t A = tet[0];
     276                 :             :                 size_t B = tet[1];
     277                 :             :                 size_t C = tet[2];
     278                 :             :                 size_t D = tet[3];
     279                 :             : 
     280                 :             :                 edge_t key;
     281                 :             : 
     282                 :             :                 key = nodes_to_key(A,B);
     283                 :     2138486 :                 key_list[0] = key;
     284                 :             : 
     285                 :             :                 key = nodes_to_key(A,C);
     286                 :     2138486 :                 key_list[1] = key;
     287                 :             : 
     288                 :             :                 key = nodes_to_key(A,D);
     289                 :     2138486 :                 key_list[2] = key;
     290                 :             : 
     291                 :             :                 key = nodes_to_key(B,C);
     292                 :     2138486 :                 key_list[3] = key;
     293                 :             : 
     294                 :             :                 key = nodes_to_key(B,D);
     295                 :     2138486 :                 key_list[4] = key;
     296                 :             : 
     297                 :             :                 key = nodes_to_key(C,D);
     298                 :     1137962 :                 key_list[5] = key;
     299                 :             : 
     300                 :             :                 return key_list;
     301                 :             :             }
     302                 :             : 
     303                 :             :             /**
     304                 :             :              * @brief Helper debug function to print edge information
     305                 :             :              */
     306                 :             :             void print() {
     307                 :             :                 for (const auto& kv : edges)
     308                 :             :                 {
     309                 :             :                     trace_out << "edge " << kv.first << " between " <<
     310                 :             :                         kv.second.A << " and " << kv.second.B <<
     311                 :             :                     std::endl;
     312                 :             :                 }
     313                 :             :             }
     314                 :             :     };
     315                 :             : }
     316                 :             : 
     317                 :             : #endif // AMR_edge_store
        

Generated by: LCOV version 2.0-1