Xyst test code coverage report
Current view: top level - Inciter/AMR - edge_store.hpp (source / functions) Hit Total Coverage
Commit: 5689ba12dc66a776d3d75f1ee48cc7d78eaa18dc Lines: 37 40 92.5 %
Date: 2024-11-22 19:02:53 Functions: 5 5 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 26 38 68.4 %

           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                 :            :             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                 :      83956 :                 generate(A, AB, lc);
      43                 :      83956 :                 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                 :            :             }
      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         [ +  + ]:     363330 :             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                 :     363330 :             }
      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                 :    5553480 :                 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                 :    5916030 :                 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                 :       3135 :             static edge_list_t generate_keys_from_face_ids(face_ids_t face_ids)
     159                 :            :             {
     160                 :            :                 edge_list_t key_list;
     161                 :       3135 :                 size_t A = face_ids[0];
     162                 :       3135 :                 size_t B = face_ids[1];
     163         [ +  + ]:       3135 :                 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                 :       3135 :                 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                 :    1975359 :             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                 :    1975359 :                 size_t A = tet[0];
     276                 :    1975359 :                 size_t B = tet[1];
     277                 :    1975359 :                 size_t C = tet[2];
     278         [ +  + ]:    1975359 :                 size_t D = tet[3];
     279                 :            : 
     280                 :            :                 edge_t key;
     281                 :            : 
     282                 :            :                 key = nodes_to_key(A,B);
     283         [ +  + ]:    1975359 :                 key_list[0] = key;
     284                 :            : 
     285                 :            :                 key = nodes_to_key(A,C);
     286         [ +  + ]:    1975359 :                 key_list[1] = key;
     287                 :            : 
     288                 :            :                 key = nodes_to_key(A,D);
     289         [ +  + ]:    1975359 :                 key_list[2] = key;
     290                 :            : 
     291                 :            :                 key = nodes_to_key(B,C);
     292         [ +  + ]:    1975359 :                 key_list[3] = key;
     293                 :            : 
     294                 :            :                 key = nodes_to_key(B,D);
     295         [ +  + ]:    1975359 :                 key_list[4] = key;
     296                 :            : 
     297                 :            :                 key = nodes_to_key(C,D);
     298                 :    1975359 :                 key_list[5] = key;
     299                 :            : 
     300                 :    1975359 :                 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 1.16