Quinoa unit test code coverage report
Current view: top level - Inciter/AMR - mesh_adapter.cpp (source / functions) Hit Total Coverage
Commit: Quinoa_v0.3-957-gb4f0efae0 Lines: 0 383 0.0 %
Date: 2021-11-09 12:13:43 Functions: 0 23 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 387 0.0 %

           Branch data     Line data    Source code
       1                 :            : #include "mesh_adapter.hpp"
       2                 :            : 
       3                 :            : #include <assert.h>                        // for assert
       4                 :            : #include <cstddef>                         // for size_t
       5                 :            : #include <iostream>                        // for operator<<, endl, basic_os...
       6                 :            : #include <set>                             // for set
       7                 :            : #include <utility>                         // for pair
       8                 :            : #include "AMR/AMR_types.hpp"                 // for Edge_Refinement, edge_list_t
       9                 :            : #include "AMR/Loggers.hpp"                   // for trace_out
      10                 :            : #include "AMR/Refinement_State.hpp"          // for Refinement_Case, Refinemen...
      11                 :            : #include "AMR/edge.hpp"                      // for operator<<, edge_t
      12                 :            : #include "AMR/edge_store.hpp"                // for edge_store_t
      13                 :            : #include "AMR/marked_refinements_store.hpp"  // for marked_refinements_store_t
      14                 :            : #include "AMR/node_connectivity.hpp"         // for node_connectivity_t
      15                 :            : #include "AMR/refinement.hpp"                // for refinement_t
      16                 :            : #include "AMR/tet_store.hpp"                 // for tet_store_t
      17                 :            : 
      18                 :            : #if defined(__clang__)
      19                 :            :   #pragma clang diagnostic push
      20                 :            :   #pragma clang diagnostic ignored "-Wunreachable-code"
      21                 :            :   #pragma clang diagnostic ignored "-Wdocumentation"
      22                 :            : #endif
      23                 :            : 
      24                 :            : namespace AMR {
      25                 :            : 
      26                 :            : 
      27                 :            : #ifdef ENABLE_NODE_STORE
      28                 :            :     /**
      29                 :            :      * @brief This accepts external coord arrays and allows the node_store to
      30                 :            :      * track the new node positions as they are added
      31                 :            :      *
      32                 :            :      * @param m_x X coodinates
      33                 :            :      * @param m_y Y coodinates
      34                 :            :      * @param m_z Z coodinates
      35                 :            :      * @param graph_size Total number of nodes
      36                 :            :      */
      37                 :            :     // TODO: remove graph size and use m.size()
      38                 :            :     // TODO: remove these pointers
      39                 :            :     //void mesh_adapter_t::init_node_store(coord_type* m_x, coord_type* m_y, coord_type* m_z)
      40                 :            :     //{
      41                 :            :     //    assert( m_x->size() == m_y->size() );
      42                 :            :     //    assert( m_x->size() == m_z->size() );
      43                 :            : 
      44                 :            :     //    node_store.set_x(*m_x);
      45                 :            :     //    node_store.set_y(*m_y);
      46                 :            :     //    node_store.set_z(*m_z);
      47                 :            :     //}
      48                 :            : #endif
      49                 :            : 
      50                 :          0 :     std::pair< bool, std::size_t > mesh_adapter_t::check_same_face(
      51                 :            :       std::size_t tet_id,
      52                 :            :       const std::unordered_set<std::size_t>& inactive_nodes)
      53                 :            :     {
      54                 :          0 :        edge_list_t edge_list = tet_store.generate_edge_keys(tet_id);
      55                 :            : 
      56                 :            :        Assert(inactive_nodes.size()==3 || inactive_nodes.size()==2,
      57                 :            :          "Incorrectly sized inactive nodes set");
      58                 :            : 
      59                 :            :        // for a tet ABCD, the keys (edges) are ordered
      60                 :            :        // A-B, A-C, A-D, B-C, B-D, C-D
      61                 :            :        // 0-1, 0-2, 0-3, 1-2, 1-3, 2-3
      62                 :            : 
      63                 :            :        std::array< std::array< std::size_t, 3 >, 4 >
      64                 :            :          edges_on_face;
      65                 :            : 
      66                 :            :        // A-B-C
      67                 :          0 :        edges_on_face[0][0] =
      68                 :          0 :          tk::cref_find(node_connectivity.data(),edge_list[0].get_data());
      69                 :          0 :        edges_on_face[0][1] =
      70                 :          0 :          tk::cref_find(node_connectivity.data(),edge_list[1].get_data());
      71                 :          0 :        edges_on_face[0][2] =
      72                 :          0 :          tk::cref_find(node_connectivity.data(),edge_list[3].get_data());
      73                 :            : 
      74                 :            :        // A-B-D
      75                 :          0 :        edges_on_face[1][0] =
      76                 :          0 :          tk::cref_find(node_connectivity.data(),edge_list[0].get_data());
      77                 :          0 :        edges_on_face[1][1] =
      78                 :          0 :          tk::cref_find(node_connectivity.data(),edge_list[2].get_data());
      79                 :          0 :        edges_on_face[1][2] =
      80                 :          0 :          tk::cref_find(node_connectivity.data(),edge_list[4].get_data());
      81                 :            : 
      82                 :            :        // B-C-D
      83                 :          0 :        edges_on_face[2][0] =
      84                 :          0 :          tk::cref_find(node_connectivity.data(),edge_list[3].get_data());
      85                 :          0 :        edges_on_face[2][1] =
      86                 :          0 :          tk::cref_find(node_connectivity.data(),edge_list[4].get_data());
      87                 :          0 :        edges_on_face[2][2] =
      88                 :          0 :          tk::cref_find(node_connectivity.data(),edge_list[5].get_data());
      89                 :            : 
      90                 :            :        // A-C-D
      91                 :          0 :        edges_on_face[3][0] =
      92                 :          0 :          tk::cref_find(node_connectivity.data(),edge_list[1].get_data());
      93                 :          0 :        edges_on_face[3][1] =
      94                 :          0 :          tk::cref_find(node_connectivity.data(),edge_list[2].get_data());
      95                 :          0 :        edges_on_face[3][2] =
      96                 :          0 :          tk::cref_find(node_connectivity.data(),edge_list[5].get_data());
      97                 :            : 
      98                 :            :        //Iterate over edges to determine if inactive_nodes are all part of a face
      99                 :            :        bool same_face(false);
     100                 :            :        [[maybe_unused]] bool tnode_set(false);
     101                 :            :        std::size_t third_node = 0;
     102         [ -  - ]:          0 :        for(const auto& face : edges_on_face)
     103                 :            :        {
     104                 :            :          std::size_t icount = 0;
     105         [ -  - ]:          0 :          for (const auto& np_node : face) {
     106         [ -  - ]:          0 :            if (inactive_nodes.count(np_node)) ++icount;
     107                 :            :          }
     108         [ -  - ]:          0 :          if (inactive_nodes.size() == icount) {
     109                 :            :            same_face = true;
     110                 :            :            // if the two inactive_nodes being checked are on the same parent
     111                 :            :            // face, determine the third node on that face
     112         [ -  - ]:          0 :            if (inactive_nodes.size() == 2) {
     113         [ -  - ]:          0 :              for (auto fn:face) {
     114         [ -  - ]:          0 :                if (inactive_nodes.count(fn) == 0) {
     115                 :            :                  third_node = fn;
     116                 :            :                  tnode_set = true;
     117                 :            :                  break;
     118                 :            :                }
     119                 :            :              }
     120                 :            :            }
     121                 :            :          }
     122                 :            :        }
     123                 :            : 
     124                 :            :        if (same_face && inactive_nodes.size() == 2)
     125                 :            :          Assert(tnode_set, "Third node on face not set in derefine");
     126                 :            : 
     127                 :          0 :        return {same_face, third_node};
     128                 :            :     }
     129                 :            : 
     130                 :            :     /** @brief Consume an existing mesh, and turn it into the AMRs
     131                 :            :      * representations of tets and nodes
     132                 :            :      *
     133                 :            :      * @param tetinpoel Vector of nodes grouped together in blocks of 4 to
     134                 :            :      * represent tets
     135                 :            :      */
     136                 :          0 :     void mesh_adapter_t::consume_tets(const std::vector< std::size_t >& tetinpoel )
     137                 :            :     {
     138         [ -  - ]:          0 :         for (size_t i = 0; i < tetinpoel.size(); i+=4)
     139                 :            :         {
     140                 :            :             tet_t t = {
     141                 :            :                 {
     142                 :            :                     tetinpoel[i],
     143                 :          0 :                     tetinpoel[i+1],
     144                 :          0 :                     tetinpoel[i+2],
     145                 :          0 :                     tetinpoel[i+3]
     146                 :            :                 }
     147                 :          0 :             };
     148                 :            : 
     149                 :            :             trace_out << "Consume tet " << i << std::endl;
     150                 :          0 :             tet_store.add(t, AMR::Refinement_Case::initial_grid);
     151                 :            :         }
     152                 :          0 :     }
     153                 :            : 
     154                 :            :     /**
     155                 :            :      * @brief Place holder function to evaluate error estimate at
     156                 :            :      * nodes, and therefor mark things as needing to be refined
     157                 :            :      */
     158                 :            :     //void mesh_adapter_t::evaluate_error_estimate() {
     159                 :            :     //    for (auto& kv : tet_store.edge_store.edges)
     160                 :            :     //    {
     161                 :            :     //        // Mark them as needing refinement
     162                 :            :     //        if (kv.second.refinement_criteria > refinement_cut_off)
     163                 :            :     //        {
     164                 :            :     //            kv.second.needs_refining = 1;
     165                 :            :     //        }
     166                 :            :     //        else
     167                 :            :     //        {
     168                 :            :     //            // TODO: Check this won't be overwriting valuable
     169                 :            :     //            // information from last iteration
     170                 :            :     //            kv.second.needs_refining = 0;
     171                 :            :     //        }
     172                 :            :     //    }
     173                 :            :     //}
     174                 :            : 
     175                 :            :     /**
     176                 :            :      * @brief Helper function to apply uniform refinement to all tets
     177                 :            :      */
     178                 :          0 :     void mesh_adapter_t::mark_uniform_refinement()
     179                 :            :     {
     180         [ -  - ]:          0 :         for (auto& kv : tet_store.edge_store.edges) {
     181                 :            :            auto& local = kv.second;
     182         [ -  - ]:          0 :            if (local.lock_case == Edge_Lock_Case::unlocked)
     183                 :          0 :              local.needs_refining = 1;
     184                 :            :         }
     185                 :          0 :         mark_refinement();
     186                 :          0 :     }
     187                 :            : 
     188                 :            :     /**
     189                 :            :      * @brief Helper function to apply uniform derefinement to all tets
     190                 :            :      */
     191                 :          0 :     void mesh_adapter_t::mark_uniform_derefinement()
     192                 :            :     {
     193                 :          0 :       const auto& inp = tet_store.get_active_inpoel();
     194                 :          0 :       auto& edge_store = tet_store.edge_store;
     195         [ -  - ]:          0 :       for (std::size_t t=0; t<inp.size()/4; ++t) {
     196                 :            :         const auto edges =
     197                 :            :           edge_store.generate_keys(
     198                 :          0 :             {inp[t*4+0], inp[t*4+1], inp[t*4+2], inp[t*4+3]});
     199         [ -  - ]:          0 :         for (const auto& tetedge : edges) {
     200                 :            :           auto e = edge_store.edges.find(tetedge);
     201         [ -  - ]:          0 :           if (e != end(edge_store.edges)) {
     202                 :            :             auto& local = e->second;
     203                 :            :             //if (local.lock_case == Edge_Lock_Case::unlocked) {
     204                 :          0 :               local.needs_derefining = 1;
     205                 :            :             //  trace_out << "edge marked for deref: " << local.A << " - "
     206                 :            :             //    << local.B << std::endl;
     207                 :            :             //}
     208                 :            :           }
     209                 :            :         }
     210                 :            :       }
     211                 :          0 :       mark_derefinement();
     212                 :          0 :     }
     213                 :            : 
     214                 :            :     /**
     215                 :            :      * @brief For a given set of edges, set their refinement criteria for
     216                 :            :      * refinement
     217                 :            :      *
     218                 :            :      * @param remote Vector of edges and edge tags
     219                 :            :      */
     220                 :          0 :     void mesh_adapter_t::mark_error_refinement(
     221                 :            :             const std::vector< std::pair< edge_t, edge_tag > >& remote )
     222                 :            :     {
     223         [ -  - ]:          0 :        for (const auto& r : remote) {
     224                 :          0 :          auto& local = tet_store.edge_store.get( r.first );
     225         [ -  - ]:          0 :          if (r.second == edge_tag::REFINE) {
     226         [ -  - ]:          0 :            if (local.lock_case > Edge_Lock_Case::unlocked) {
     227                 :          0 :              local.needs_refining = 0;
     228                 :            :            } else {
     229                 :          0 :              local.needs_refining = 1;
     230                 :            :              // an edge deemed to be 'needing refinement', cannot be derefined
     231                 :          0 :              local.needs_derefining = 0;
     232                 :            :            }
     233         [ -  - ]:          0 :          } else if (r.second == edge_tag::DEREFINE) {
     234         [ -  - ]:          0 :            if (local.lock_case > Edge_Lock_Case::unlocked) {
     235                 :          0 :              local.needs_derefining = 0;
     236                 :            :            } else {
     237                 :          0 :              local.needs_derefining = 1;
     238                 :            :            }
     239                 :            :          }
     240                 :            :        }
     241                 :            : 
     242                 :          0 :        mark_refinement();
     243                 :          0 :        mark_derefinement();
     244                 :          0 :     }
     245                 :            : 
     246                 :          0 :    void mesh_adapter_t::mark_error_refinement_corr( const EdgeData& edges )
     247                 :            :     {
     248         [ -  - ]:          0 :        for (const auto& r : edges)
     249                 :            :        {
     250                 :          0 :            auto& edgeref = tet_store.edge_store.get( edge_t(r.first) );
     251                 :          0 :            edgeref.needs_refining = r.second.first;
     252                 :            :            assert(edgeref.lock_case <= r.second.second);
     253                 :          0 :            edgeref.lock_case = r.second.second;
     254                 :            :        }
     255                 :          0 :        mark_refinement();
     256                 :          0 :     }
     257                 :            : 
     258                 :            :     /**
     259                 :            :      * @brief Function to detect the compatibility class (1,
     260                 :            :      * 2, or 3) based on the number of locked edges and the existence
     261                 :            :      * of intermediate edges
     262                 :            :      *
     263                 :            :      * @param num_locked_edges The number of locked edges
     264                 :            :      * @param num_intermediate_edges The number of intermediate edges
     265                 :            :      * @param refinement_case The refinement case of the tet
     266                 :            :      * @param normal TODO: Document this!
     267                 :            :      *
     268                 :            :      * @return The compatibili4y class of the current scenario
     269                 :            :      */
     270                 :          0 :     int mesh_adapter_t::detect_compatibility(
     271                 :            :             int num_locked_edges,
     272                 :            :             int num_intermediate_edges,
     273                 :            :             AMR::Refinement_Case refinement_case,
     274                 :            :             int normal
     275                 :            :     )
     276                 :            :     {
     277                 :            :         int compatibility = 0;
     278                 :          0 :         num_locked_edges += num_intermediate_edges;
     279                 :            : 
     280                 :            :         /*
     281                 :            :         // Split this into three categories
     282                 :            :         // 1. Normal elements without locked edges. => 1
     283                 :            :         //if (normal) {
     284                 :            : 
     285                 :            :             // 3. Intermediate elements with at least one edge marked for refinement => 3
     286                 :            :             if (num_intermediate_edges > 0)
     287                 :            :             {
     288                 :            :                 compatibility = 3;
     289                 :            :             }
     290                 :            :             else if (num_locked_edges == 0) {
     291                 :            :                 compatibility = 1;
     292                 :            :             }
     293                 :            :         // 2. Normal elements with locked edges. => 2
     294                 :            :             else {
     295                 :            :                 compatibility = 2;
     296                 :            :             }
     297                 :            :         //}
     298                 :            :         */
     299                 :            : 
     300                 :            :         //else {
     301                 :            :             //if (num_intermediate_edges > 0) { compatibility = 3; }
     302                 :            :         //}
     303                 :            : 
     304                 :            : 
     305                 :            : 
     306                 :            :         // Only 1:2 and 1:4 are intermediates and eligible for class3 // NOT TRUE!
     307                 :            :         /*
     308                 :            :         if (num_intermediate_edges > 0)
     309                 :            :         {
     310                 :            :             if (!normal) {
     311                 :            :                 trace_out << " not normal 3 " << std::endl;
     312                 :            :                 compatibility = 3;
     313                 :            :             }
     314                 :            :             else { // Attempt to allow for "normal" 1:4 and 1:8
     315                 :            :                 compatibility = 2;
     316                 :            :                 trace_out << " normal 3 " << std::endl;
     317                 :            :             }
     318                 :            : 
     319                 :            :         }
     320                 :            :         else {
     321                 :            :             if (num_locked_edges == 0) {
     322                 :            :                 trace_out << " no lock 1 " << std::endl;
     323                 :            :                 compatibility = 1;
     324                 :            :             }
     325                 :            :             else {
     326                 :            :                 trace_out << " lock 2 " << std::endl;
     327                 :            :                 compatibility = 2;
     328                 :            :             }
     329                 :            :         }
     330                 :            :         */
     331                 :            : 
     332                 :            : 
     333                 :            :         // Old implementation
     334                 :            :         // Only 1:2 and 1:4 are intermediates and eligible for class3 // NOT TRUE!
     335                 :          0 :         if (
     336         [ -  - ]:          0 :                 (refinement_case == AMR::Refinement_Case::one_to_two) or
     337                 :            :                 (refinement_case == AMR::Refinement_Case::one_to_four)
     338                 :            :            )
     339                 :            :         {
     340         [ -  - ]:          0 :             if (!normal) {
     341                 :            :                 trace_out << " not normal 3 " << std::endl;
     342                 :            :                 compatibility = 3;
     343                 :            :             }
     344                 :            :             else { // Attempt to allow for "normal" 1:4 and 1:8
     345                 :            :                 compatibility = 2;
     346                 :            :                 trace_out << " normal 3 " << std::endl;
     347                 :            :             }
     348                 :            : 
     349                 :            :         }
     350                 :            :         else {
     351         [ -  - ]:          0 :             if (num_locked_edges == 0) {
     352                 :            :                 trace_out << " no lock 1 " << std::endl;
     353                 :            :                 compatibility = 1;
     354                 :            :             }
     355                 :            :             else {
     356                 :            :                 trace_out << " lock 2 " << std::endl;
     357                 :            :                 compatibility = 2;
     358                 :            :             }
     359                 :            :         }
     360                 :            : 
     361                 :            :         assert(compatibility > 0);
     362                 :            :         assert(compatibility < 4);
     363                 :          0 :         return compatibility;
     364                 :            :     }
     365                 :            : 
     366                 :            :     /**
     367                 :            :      * @brief Function which implements the main refinement algorithm from
     368                 :            :      * the paper Iterating over the cells, deciding which refinement and
     369                 :            :      * compatibility types are appropriate etc
     370                 :            :      */
     371                 :          0 :     void mesh_adapter_t::mark_refinement() {
     372                 :            : 
     373                 :            : #ifndef AMR_MAX_ROUNDS
     374                 :            :         // Paper says the average actual num rounds will be 5-15
     375                 :            : #define AMR_MAX_ROUNDS 50
     376                 :            : #endif
     377                 :            :         const size_t max_num_rounds = AMR_MAX_ROUNDS;
     378                 :            : 
     379                 :            :         // Mark refinements
     380                 :            :         size_t iter;
     381                 :            :         //Iterate until convergence
     382         [ -  - ]:          0 :         for (iter = 0; iter < max_num_rounds; iter++)
     383                 :            :         {
     384                 :            : 
     385                 :          0 :             tet_store.marked_refinements.get_state_changed() = false;
     386                 :            : 
     387                 :            :             // Loop over Tets.
     388         [ -  - ]:          0 :             for (const auto& kv : tet_store.tets)
     389                 :            :             {
     390                 :          0 :                 size_t tet_id = kv.first;
     391                 :            : 
     392                 :            :                 trace_out << "Process tet " << tet_id << std::endl;
     393                 :            : 
     394                 :            :                 // Only apply checks to tets on the active list
     395                 :            :                 if (tet_store.is_active(tet_id)) {
     396                 :            :                     int num_locked_edges = 0;
     397                 :            :                     int num_intermediate_edges = 0;
     398                 :            : 
     399                 :            :                     // Loop over nodes and count the number which need refining
     400                 :            :                     int num_to_refine = 0;
     401                 :            : 
     402                 :            :                     // This is useful for later inspection
     403                 :          0 :                     edge_list_t edge_list = tet_store.generate_edge_keys(tet_id);
     404                 :            : 
     405                 :            :                     //Iterate over edges
     406         [ -  - ]:          0 :                     for(auto & key : edge_list)
     407                 :            :                     {
     408                 :            : 
     409                 :            :                         trace_out << "Edge " << key << std::endl;
     410                 :            : 
     411                 :            :                         //Count locked edges and edges in need of
     412                 :            :                         // refinement
     413                 :            :                         // Count Locked Edges
     414         [ -  - ]:          0 :                         if(tet_store.edge_store.get(key).lock_case == AMR::Edge_Lock_Case::locked)
     415                 :            :                         {
     416                 :            :                             trace_out << "Found locked edge " << key << std::endl;
     417                 :            :                             trace_out << "Locked :" << tet_store.edge_store.get(key).lock_case << std::endl;
     418                 :          0 :                             num_locked_edges++;
     419                 :            :                         }
     420         [ -  - ]:          0 :                         else if(tet_store.edge_store.get(key).lock_case == AMR::Edge_Lock_Case::intermediate)
     421                 :            :                         {
     422                 :            :                             trace_out << "Found intermediate edge " << key << std::endl;
     423                 :          0 :                             num_intermediate_edges++;
     424                 :            :                         }
     425                 :            :                         else
     426                 :            :                         {
     427                 :            :                             // Count edges which need refining
     428                 :            :                             //  We check in here as we won't refine a
     429                 :            :                             //  locked edge and will thus ignore it
     430         [ -  - ]:          0 :                             if (tet_store.edge_store.get(key).needs_refining == 1)
     431                 :            :                             {
     432                 :          0 :                                 num_to_refine++;
     433                 :            :                                 trace_out << "key needs ref " << key << std::endl;
     434                 :            :                             }
     435                 :            :                         }
     436                 :            :                     }
     437                 :            : 
     438                 :            :                     // TODO: Should this be a reference?
     439                 :            :                     AMR::Refinement_Case refinement_case = tet_store.get_refinement_case(tet_id);
     440                 :          0 :                     int normal = tet_store.is_normal(tet_id);
     441                 :            : 
     442                 :            :                     trace_out << "Checking " << tet_id <<
     443                 :            :                         " ref case " << refinement_case <<
     444                 :            :                         " num ref " << num_to_refine <<
     445                 :            :                         " normal " << normal <<
     446                 :            :                         std::endl;
     447                 :            : 
     448                 :            : 
     449                 :            : 
     450                 :            :                     //If we have any tets to refine
     451         [ -  - ]:          0 :                     if (num_to_refine > 0)
     452                 :            :                     {
     453                 :            :                         //Determine compatibility case
     454                 :            : 
     455                 :          0 :                         int compatibility = detect_compatibility(num_locked_edges,
     456                 :            :                                 num_intermediate_edges, refinement_case, normal);
     457                 :            : 
     458                 :            :                         trace_out << "Compat " << compatibility << std::endl;
     459                 :            : 
     460                 :            :                         // Now check num_to_refine against situations
     461         [ -  - ]:          0 :                         if (compatibility == 1)
     462                 :            :                         {
     463                 :          0 :                             refinement_class_one(num_to_refine, tet_id);
     464                 :            :                         }
     465         [ -  - ]:          0 :                         else if (compatibility == 2)
     466                 :            :                         {
     467                 :          0 :                             refinement_class_two(edge_list, tet_id);
     468                 :            :                         }
     469         [ -  - ]:          0 :                         else if (compatibility == 3)
     470                 :            :                         {
     471                 :          0 :                             refinement_class_three(tet_id);
     472                 :            :                         }
     473                 :            : 
     474                 :            :                         /*
     475                 :            :                         // Write temp mesh out
     476                 :            :                         std::string temp_file =  "temp." +
     477                 :            :                         std::to_string(iter) + "." +
     478                 :            :                         std::to_string(tet_id) + ".exo";
     479                 :            : 
     480                 :            :                         std::cout << "Writing " << temp_file << std::endl;
     481                 :            :                         Adaptive_UnsMesh outmesh(
     482                 :            :                         get_active_inpoel(), x(), y(), z()
     483                 :            :                         );
     484                 :            :                         tk::ExodusIIMeshWriter( temp_file, tk::ExoWriter::CREATE ).
     485                 :            :                         writeMesh(outmesh);
     486                 :            :                         */
     487                 :            : 
     488                 :            :                     } // if num_to_refine
     489                 :            :                     else {
     490                 :            :                         // If we got here, we don't want to refine this guy
     491                 :          0 :                         tet_store.marked_refinements.add(tet_id, AMR::Refinement_Case::none);
     492                 :            :                     }
     493                 :            :                 } // if active
     494                 :            :                 else {
     495                 :            :                     trace_out << "Inactive" << std::endl;
     496                 :            :                 }
     497                 :            :             } // For
     498                 :            : 
     499                 :            :             // If nothing changed during that round, break
     500         [ -  - ]:          0 :             if (!tet_store.marked_refinements.get_state_changed())
     501                 :            :             {
     502                 :            :                 trace_out << "Terminating loop at iter " << iter << std::endl;
     503                 :            :                 break;
     504                 :            :             }
     505                 :            :             trace_out << "End iter " << iter << std::endl;
     506                 :            :         }
     507                 :            :         trace_out << "Loop took " << iter << " rounds." << std::endl;
     508                 :            : 
     509                 :            :         //std::cout << "Print Tets" << std::endl;
     510                 :            :         //print_tets();
     511                 :          0 :     }
     512                 :            : 
     513                 :            :     /**
     514                 :            :      * @brief Helper function to print tet information when needed
     515                 :            :      */
     516                 :          0 :     void mesh_adapter_t::print_tets() {
     517                 :            :         tet_store.print_tets();
     518                 :          0 :     }
     519                 :            : 
     520                 :            :     /**
     521                 :            :      * @brief Function to call refinement after each tet has had it's
     522                 :            :      * refinement case marked and calculated
     523                 :            :      */
     524                 :          0 :     void mesh_adapter_t::perform_refinement()
     525                 :            :     {
     526                 :            :         // Track tets which need to be deleted this iteration
     527                 :            :         std::set<size_t> round_two;
     528                 :            : 
     529                 :            :         trace_out << "Perform ref" << std::endl;
     530                 :            : 
     531                 :            :         // Do refinements
     532         [ -  - ]:          0 :         for (const auto& kv : tet_store.tets)
     533                 :            :         {
     534                 :          0 :             size_t tet_id = kv.first;
     535                 :            : 
     536                 :            :             trace_out << "Do refine of " << tet_id << std::endl;
     537                 :            :             if (tet_store.has_refinement_decision(tet_id))
     538                 :            :             {
     539 [ -  - ][ -  - ]:          0 :                 switch(tet_store.marked_refinements.get(tet_id))
                 [ -  - ]
     540                 :            :                 {
     541                 :          0 :                     case AMR::Refinement_Case::one_to_two:
     542         [ -  - ]:          0 :                         refiner.refine_one_to_two(tet_store,node_connectivity,tet_id);
     543                 :            :                         break;
     544                 :          0 :                     case AMR::Refinement_Case::one_to_four:
     545         [ -  - ]:          0 :                         refiner.refine_one_to_four(tet_store,node_connectivity,tet_id);
     546                 :            :                         break;
     547                 :          0 :                     case AMR::Refinement_Case::one_to_eight:
     548         [ -  - ]:          0 :                         refiner.refine_one_to_eight(tet_store,node_connectivity,tet_id);
     549                 :            :                         break;
     550         [ -  - ]:          0 :                     case AMR::Refinement_Case::two_to_eight:
     551         [ -  - ]:          0 :                         round_two.insert( tet_store.get_parent_id(tet_id) );
     552                 :            :                         //std::cout << "2->8\n";
     553                 :          0 :                         break;
     554         [ -  - ]:          0 :                     case AMR::Refinement_Case::four_to_eight:
     555         [ -  - ]:          0 :                         round_two.insert( tet_store.get_parent_id(tet_id));
     556                 :            :                         //std::cout << "4->8\n";
     557                 :          0 :                         break;
     558                 :            :                     case AMR::Refinement_Case::initial_grid:
     559                 :            :                         // Do nothing
     560                 :            :                     case AMR::Refinement_Case::none:
     561                 :            :                         // Do nothing
     562                 :            :                         break;
     563                 :            :                         // No need for default as enum is explicitly covered
     564                 :            :                 }
     565                 :            :                 // Mark tet as not needing refinement
     566                 :          0 :                 tet_store.marked_refinements.erase(tet_id);
     567                 :            :             }
     568                 :            :         }
     569                 :            : 
     570                 :            :         trace_out << "round_two size " << round_two.size() << std::endl;
     571 [ -  - ][ -  - ]:          0 :         for (const auto i : round_two)
     572                 :            :         {
     573                 :            :             trace_out << "round two i " << i << std::endl;
     574                 :            : 
     575                 :            :             // Cache children as we're about to change this data
     576         [ -  - ]:          0 :             auto former_children = tet_store.data(i).children;
     577                 :            : 
     578                 :            :             AMR::Refinement_State& element = tet_store.data(i);
     579                 :            : 
     580         [ -  - ]:          0 :             if (element.children.size() == 2)
     581                 :            :             {
     582                 :            :                 trace_out << "perform 2:8" << std::endl;
     583         [ -  - ]:          0 :                 refiner.derefine_two_to_one(tet_store,node_connectivity,i);
     584                 :            :             }
     585         [ -  - ]:          0 :             else if (element.children.size() == 4)
     586                 :            :             {
     587                 :            :                 trace_out << "perform 4:8" << std::endl;
     588         [ -  - ]:          0 :                 refiner.derefine_four_to_one(tet_store,node_connectivity,i);
     589                 :            :             }
     590                 :            :             else {
     591         [ -  - ]:          0 :                 std::cout << "num children " << element.children.size() << std::endl;
     592                 :            :                 assert(0);
     593                 :            :             }
     594                 :            :             // remove tets and edges marked for deletion above
     595                 :          0 :             refiner.delete_intermediates_of_children(tet_store);
     596                 :          0 :             tet_store.process_delete_list();
     597                 :            : 
     598         [ -  - ]:          0 :             refiner.refine_one_to_eight(tet_store,node_connectivity,i);
     599                 :            : 
     600                 :            :             // Grab children after it has been updated
     601         [ -  - ]:          0 :             auto current_children = tet_store.data(i).children;
     602                 :            : 
     603                 :            :             // I want to set the children stored in *my* own children, to be
     604                 :            :             // the value of my new children....
     605                 :            :             //refiner.overwrite_children(tet_store, former_children, current_children);
     606                 :            : 
     607         [ -  - ]:          0 :             tet_store.unset_marked_children(i); // FIXME: This will not work well in parallel
     608         [ -  - ]:          0 :             element.refinement_case = AMR::Refinement_Case::one_to_eight;
     609                 :            :         }
     610                 :            : 
     611                 :            :         // Clean up dead edges
     612                 :            :         // clean_up_dead_edges(); // Nothing get's marked as "dead" atm?
     613                 :            : 
     614                 :            :         //std::cout << "Total Edges : " << tet_store.edge_store.size() << std::endl;
     615                 :            :         //std::cout << "Total Tets : " << tet_store.size() << std::endl;
     616                 :            :         //std::cout << "Total Nodes : " << m_x.size() << std::endl;
     617                 :            : 
     618                 :            :         trace_out << "Done ref" << std::endl;
     619                 :            :         node_connectivity.print();
     620                 :            :         node_connectivity.print();
     621         [ -  - ]:          0 :         tet_store.print_node_types();
     622                 :            :         tet_store.print_tets();
     623                 :            :         //node_connectivity.print();
     624                 :            : 
     625                 :            :         //reset_intermediate_edges();
     626         [ -  - ]:          0 :         remove_edge_locks(1);
     627         [ -  - ]:          0 :         remove_normals();
     628                 :            : 
     629         [ -  - ]:          0 :         lock_intermediates();
     630                 :            : 
     631         [ -  - ]:          0 :         for (auto& kv : tet_store.edge_store.edges) {
     632                 :            :            auto& local = kv.second;
     633                 :          0 :            local.needs_refining = 0;
     634                 :            :         }
     635                 :          0 :     }
     636                 :            : 
     637                 :          0 :     void mesh_adapter_t::lock_intermediates()
     638                 :            :     {
     639                 :            :         /*
     640                 :            :         for (auto k : tet_store.intermediate_list)
     641                 :            :         {
     642                 :            :             refiner.lock_edges_from_node(tet_store,k, Edge_Lock_Case::intermediate);
     643                 :            :         }
     644                 :            :         */
     645                 :            :         // TODO: Passing tet_store twice probably isn't the best
     646         [ -  - ]:          0 :         refiner.lock_intermediates(tet_store, tet_store.intermediate_list, Edge_Lock_Case::intermediate);
     647                 :          0 :     }
     648                 :            : 
     649                 :            :     /**
     650                 :            :      * @brief A method implementing "Algorithm 1" from the paper
     651                 :            :      *
     652                 :            :      * @param num_to_refine Number of edges to refine
     653                 :            :      * @param tet_id The id of the given tet
     654                 :            :      */
     655                 :          0 :     void mesh_adapter_t::refinement_class_one(int num_to_refine, size_t tet_id)
     656                 :            :     {
     657                 :            :         trace_out << "Refinement Class One" << std::endl;
     658                 :            : 
     659                 :            :         // "If nrefine = 1
     660                 :            :         // Accept as a 1:2 refinement"
     661         [ -  - ]:          0 :         if (num_to_refine == 1)
     662                 :            :         {
     663                 :            :             tet_store.mark_one_to_two(tet_id);
     664                 :            :         }
     665                 :            : 
     666                 :            :         // "Else if nrefine = 2 OR nrefine = 3"
     667         [ -  - ]:          0 :         else if (num_to_refine > 1 && num_to_refine < 4)
     668                 :            :         {
     669                 :            : 
     670                 :            :             // We need to detect if the edges which need to refine are
     671                 :            :             // on the same face
     672                 :            :             // and if so which face so we know how to 1:4
     673                 :            : 
     674                 :          0 :             face_list_t face_list = tet_store.generate_face_lists(tet_id);
     675                 :            :             bool edges_on_same_face = false;
     676                 :            :             size_t face_refine_id = 0;
     677                 :            : 
     678                 :            :             // Iterate over each face
     679         [ -  - ]:          0 :             for (size_t face = 0; face < NUM_TET_FACES; face++)
     680                 :            :             {
     681                 :            :                 int num_face_refine_edges = 0;
     682                 :          0 :                 face_ids_t face_ids = face_list[face];
     683                 :            : 
     684                 :            :                 trace_out << "Face is " <<
     685                 :            :                     face_ids[0] << ", " <<
     686                 :            :                     face_ids[1] << ", " <<
     687                 :            :                     face_ids[2] << ", " <<
     688                 :            :                     std::endl;
     689                 :            : 
     690                 :          0 :                 edge_list_t face_edge_list = AMR::edge_store_t::generate_keys_from_face_ids(face_ids);
     691                 :            :                 // For this face list, see which ones need refining
     692         [ -  - ]:          0 :                 for (size_t k = 0; k < NUM_FACE_NODES; k++)
     693                 :            :                 {
     694                 :          0 :                     edge_t key = face_edge_list[k];
     695         [ -  - ]:          0 :                     if (tet_store.edge_store.get(key).needs_refining == 1)
     696                 :            :                     {
     697                 :          0 :                         num_face_refine_edges++;
     698                 :            :                     }
     699                 :            :                 }
     700         [ -  - ]:          0 :                 if (num_face_refine_edges == num_to_refine)
     701                 :            :                 {
     702                 :            :                     edges_on_same_face = true;
     703                 :            :                     face_refine_id = face;
     704                 :            :                     trace_out << "Breaking with face value " << face << std::endl;
     705                 :          0 :                     break;
     706                 :            :                 }
     707                 :            :             }
     708                 :            : 
     709                 :            :             // "If active edges are on the same face
     710                 :            :             // Activate any inactive edges of the face
     711                 :            :             // Accept as a 1:4 // refinement"
     712                 :            :             if (edges_on_same_face)
     713                 :            :             {
     714                 :            :                 size_t opposite_offset = AMR::node_connectivity_t::face_list_opposite(face_list,
     715                 :            :                         face_refine_id);
     716                 :            : 
     717                 :          0 :                 tet_t tet = tet_store.get(tet_id);
     718                 :            :                 size_t opposite_id = tet[opposite_offset];
     719                 :            : 
     720                 :            :                 trace_out << "face_refine_id " << face_refine_id << std::endl;
     721                 :            :                 trace_out << "opposite_offset " << opposite_offset << std::endl;
     722                 :            :                 trace_out << "opposite_id " << opposite_id << std::endl;
     723                 :            : 
     724                 :            :                 // Activate edges on this face
     725                 :          0 :                 edge_list_t face_edge_list = AMR::edge_store_t::generate_keys_from_face_ids(face_list[face_refine_id]);
     726                 :            : 
     727         [ -  - ]:          0 :                 for (size_t k = 0; k < NUM_FACE_NODES; k++)
     728                 :            :                 {
     729                 :          0 :                     edge_t key = face_edge_list[k];
     730                 :          0 :                     tet_store.edge_store.mark_for_refinement(key);
     731                 :            :                 }
     732                 :            : 
     733                 :            :                 //refiner.refine_one_to_four(tet_id, face_list[face_refine_id],
     734                 :            :                 //opposite_id);
     735                 :            :                 tet_store.mark_one_to_four(tet_id);
     736                 :            :             }
     737                 :            :             // "Else if active edges are not on the same face
     738                 :            :             // Activate all edges
     739                 :            :             // Accept as a 1:8 refinement"
     740                 :            :             else {
     741                 :            :                 //refiner.refine_one_to_eight(tet_id);
     742                 :          0 :                 tet_store.mark_edges_for_refinement(tet_id);
     743                 :            :                 tet_store.mark_one_to_eight(tet_id);
     744                 :            :             }
     745                 :            : 
     746                 :            :         }
     747                 :            : 
     748                 :            :         // "Else if nrefine > 3
     749                 :            :         // Activate any inactive edges
     750                 :            :         // Accept as a 1:8 refinement"
     751         [ -  - ]:          0 :         else if (num_to_refine > 3)
     752                 :            :         {
     753                 :            :             //refiner.refine_one_to_eight(tet_id);
     754                 :          0 :             tet_store.mark_edges_for_refinement(tet_id);
     755                 :            :             tet_store.mark_one_to_eight(tet_id);
     756                 :            :         }
     757                 :          0 :     }
     758                 :            : 
     759                 :            :     // TODO: Document this
     760                 :          0 :     void mesh_adapter_t::lock_tet_edges(size_t tet_id) {
     761                 :          0 :         edge_list_t edge_list = tet_store.generate_edge_keys(tet_id);
     762         [ -  - ]:          0 :         for (size_t k = 0; k < NUM_TET_EDGES; k++)
     763                 :            :         {
     764                 :          0 :             edge_t key = edge_list[k];
     765         [ -  - ]:          0 :             if (tet_store.edge_store.get(key).lock_case == AMR::Edge_Lock_Case::unlocked)
     766                 :            :             {
     767                 :            :                 trace_out << "LOCKING! " << key << std::endl;
     768                 :          0 :                 tet_store.edge_store.get(key).lock_case = AMR::Edge_Lock_Case::locked;
     769                 :            :             }
     770                 :            :         }
     771                 :          0 :     }
     772                 :            : 
     773                 :            :     // TODO: Document this
     774                 :            :     // TODO: This has too similar a name to deactivate_tet
     775                 :          0 :     void mesh_adapter_t::deactivate_tet_edges(size_t tet_id) {
     776                 :          0 :         edge_list_t edge_list = tet_store.generate_edge_keys(tet_id);
     777         [ -  - ]:          0 :         for (size_t k = 0; k < NUM_TET_EDGES; k++)
     778                 :            :         {
     779                 :          0 :             edge_t key = edge_list[k];
     780                 :            : 
     781                 :          0 :             tet_store.edge_store.unmark_for_refinement(key);
     782                 :            :             trace_out << "Deactivating " << key << std::endl;
     783                 :          0 :             tet_store.edge_store.get(key).needs_derefining = false;
     784                 :            :         }
     785                 :          0 :     }
     786                 :            : 
     787                 :            :     /**
     788                 :            :      * @brief Unmarks edges of given tet for derefinement only
     789                 :            :      *
     790                 :            :      * @param tet_id The id of the given tet
     791                 :            :      */
     792                 :          0 :     void mesh_adapter_t::deactivate_deref_tet_edges(size_t tet_id) {
     793                 :          0 :         edge_list_t edge_list = tet_store.generate_edge_keys(tet_id);
     794         [ -  - ]:          0 :         for (size_t k = 0; k < NUM_TET_EDGES; k++)
     795                 :            :         {
     796                 :          0 :             edge_t key = edge_list[k];
     797                 :            : 
     798                 :            :             trace_out << "Deactivating " << key << std::endl;
     799                 :          0 :             tet_store.edge_store.get(key).needs_derefining = false;
     800                 :            :         }
     801                 :          0 :     }
     802                 :            : 
     803                 :            :     /**
     804                 :            :      * @brief An implementation of "Algorithm 2" from the paper
     805                 :            :      *
     806                 :            :      * @param edge_list The list of edges for the given tet
     807                 :            :      * @param tet_id The id of the given tet
     808                 :            :      */
     809                 :          0 :     void mesh_adapter_t::refinement_class_two(edge_list_t edge_list, size_t tet_id)
     810                 :            :     {
     811                 :            :         trace_out << "Refinement Class Two" << std::endl;
     812                 :            : 
     813                 :            : 
     814                 :            :         // "Deactivate all locked edges"
     815                 :            : 
     816                 :            :         // count number of active edges
     817                 :            :         int num_active_edges = 0;
     818         [ -  - ]:          0 :         for (size_t k = 0; k < NUM_TET_EDGES; k++)
     819                 :            :         {
     820                 :          0 :             edge_t key = edge_list[k];
     821         [ -  - ]:          0 :             if (tet_store.edge_store.get(key).lock_case != AMR::Edge_Lock_Case::unlocked)
     822                 :            :             {
     823                 :            :                 tet_store.edge_store.unmark_for_refinement(key);
     824                 :            :             }
     825                 :            :             // "Count number of active edges"
     826         [ -  - ]:          0 :             if (tet_store.edge_store.get(key).needs_refining == 1) {
     827                 :          0 :                 num_active_edges++;
     828                 :            :             }
     829                 :            :         }
     830                 :            : 
     831                 :            :         // Find out of two active edges live on the same face
     832                 :            :         bool face_refine = false;
     833                 :            :         size_t face_refine_id = 0; // FIXME: Does this need a better default
     834                 :          0 :         face_list_t face_list = tet_store.generate_face_lists(tet_id);
     835                 :            : 
     836                 :            :         // Iterate over each face
     837         [ -  - ]:          0 :         for (size_t face = 0; face < NUM_TET_FACES; face++)
     838                 :            :         {
     839                 :            :             trace_out << "face " << face << std::endl;
     840                 :            :             int num_face_refine_edges = 0;
     841                 :            :             int num_face_locked_edges = 0;
     842                 :            : 
     843                 :          0 :             face_ids_t face_ids = face_list[face];
     844                 :          0 :             edge_list_t face_edge_list = AMR::edge_store_t::generate_keys_from_face_ids(face_ids);
     845                 :            :             // For this face list, see which ones need refining
     846         [ -  - ]:          0 :             for (size_t k = 0; k < NUM_FACE_NODES; k++)
     847                 :            :             {
     848                 :          0 :                 edge_t key = face_edge_list[k];
     849                 :            :                 trace_out << "Checking " << key << std::endl;
     850         [ -  - ]:          0 :                 if (tet_store.edge_store.get(key).needs_refining == 1)
     851                 :            :                 {
     852                 :          0 :                     num_face_refine_edges++;
     853                 :            :                     trace_out << "ref! " << key << std::endl;
     854                 :            :                 }
     855                 :            : 
     856                 :            :                 // Check for locked edges
     857                 :            :                 // This case only cares about faces with no locks
     858         [ -  - ]:          0 :                 if (tet_store.edge_store.get(key).lock_case != AMR::Edge_Lock_Case::unlocked)
     859                 :            :                 {
     860                 :          0 :                     num_face_locked_edges++;
     861                 :            :                     trace_out << "locked! " << key << std::endl;
     862                 :            :                 }
     863                 :            :             }
     864                 :            : 
     865                 :            : 
     866                 :            :             // Decide if we want to process this face
     867         [ -  - ]:          0 :             if (num_face_refine_edges >= 2 && num_face_locked_edges == 0)
     868                 :            :             {
     869                 :            :                 // We can refine this face
     870                 :            :                 face_refine = true;
     871                 :            :                 face_refine_id = face;
     872                 :          0 :                 break;
     873                 :            :             }
     874                 :            :         }
     875                 :            : 
     876                 :            :         // "If nrefine = 1
     877                 :            :         // Accept as 1:2 refinement"
     878                 :            :         // TODO: can we hoist this higher
     879         [ -  - ]:          0 :         if (num_active_edges == 1)
     880                 :            :         {
     881                 :            :             //node_pair_t nodes = find_single_refinement_nodes(edge_list);
     882                 :            :             //refine_one_to_two( tet_id, nodes[0], nodes[1]);
     883                 :            :             tet_store.mark_one_to_two(tet_id);
     884                 :            :         }
     885                 :            :         // "Else if any face has nrefine >= 2 AND no locked edges
     886                 :            :         // Active any inactive edges of the face
     887                 :            :         // Accept as a 1:4 refinement"
     888         [ -  - ]:          0 :         else if (face_refine)
     889                 :            :         {
     890                 :            :             size_t opposite_offset = AMR::node_connectivity_t::face_list_opposite(face_list, face_refine_id);
     891                 :            : 
     892                 :          0 :             tet_t tet = tet_store.get(tet_id);
     893                 :            :             size_t opposite_id = tet[opposite_offset];
     894                 :            : 
     895                 :            :             trace_out << "Tet ID " << tet_id << std::endl;
     896                 :            :             trace_out << "Opposite offset " << opposite_offset << std::endl;
     897                 :            :             trace_out << "Opposite id " << opposite_id << std::endl;
     898                 :            :             trace_out << "Face refine id " << face_refine_id << std::endl;
     899                 :            : 
     900                 :            :             edge_list_t face_edge_list =
     901                 :          0 :                 AMR::edge_store_t::generate_keys_from_face_ids(face_list[face_refine_id]);
     902                 :            : 
     903         [ -  - ]:          0 :             for (size_t k = 0; k < NUM_FACE_NODES; k++)
     904                 :            :             {
     905                 :          0 :                 edge_t key = face_edge_list[k];
     906                 :          0 :                 tet_store.edge_store.mark_for_refinement(key);
     907                 :            :             }
     908                 :            : 
     909                 :            :             //refiner.refine_one_to_four(tet_id, face_list[face_refine_id], opposite_id);
     910                 :            :             tet_store.mark_one_to_four(tet_id);
     911                 :            :         }
     912                 :            : 
     913                 :            :         // "Else
     914                 :            :         // Deactivate all edges
     915                 :            :         // Mark all edges as locked"
     916                 :            :         else {
     917                 :            :             trace_out << "Class 2 causes some locking.." << std::endl;
     918                 :          0 :             deactivate_tet_edges(tet_id);
     919                 :          0 :             lock_tet_edges(tet_id);
     920                 :            :         }
     921                 :            : 
     922                 :          0 :     }
     923                 :            : 
     924                 :            :     /**
     925                 :            :      * @brief Based on a tet_id, decide if it's current state of locked
     926                 :            :      * and marked edges maps to a valid refinement case. The logic for
     927                 :            :      * this was derived from talking to JW and reading Chicoma.
     928                 :            :      *
     929                 :            :      * It basically just checks if something a 1:2 and has 3
     930                 :            :      * intermediates and 3 makred edges, or is a 1:4 and has 5/6
     931                 :            :      * intermediates
     932                 :            :      *
     933                 :            :      * @param child_id the id of the tet to check
     934                 :            :      *
     935                 :            :      * @return A bool saying if the tet is in a valid state to be refined
     936                 :            :      */
     937                 :          0 :     bool mesh_adapter_t::check_valid_refinement_case(size_t child_id) {
     938                 :            : 
     939                 :            :         trace_out << "check valid ref " << child_id << std::endl;
     940                 :          0 :         edge_list_t edge_list = tet_store.generate_edge_keys(child_id);
     941                 :            : 
     942                 :            :         size_t num_to_refine = 0;
     943                 :            :         size_t num_intermediate = 0;
     944                 :            :         size_t unlocked = 0;
     945                 :            :         size_t locked = 0;
     946                 :            : 
     947         [ -  - ]:          0 :         for (size_t k = 0; k < NUM_TET_EDGES; k++)
     948                 :            :         {
     949                 :          0 :             edge_t key = edge_list[k];
     950                 :            :             trace_out << "Key " << key << std::endl;
     951                 :            : 
     952                 :            :             // Count intermediate edges
     953         [ -  - ]:          0 :             if (tet_store.edge_store.get(key).lock_case == AMR::Edge_Lock_Case::intermediate)
     954                 :            :             {
     955                 :            :                 trace_out << "found intermediate" << std::endl;
     956                 :          0 :                 num_intermediate++;
     957                 :            :             }
     958                 :            : 
     959                 :            :             // Count number of marked for refinement
     960         [ -  - ]:          0 :             if (tet_store.edge_store.get(key).needs_refining == 1)
     961                 :            :             {
     962                 :            :                 trace_out << "found refine" << std::endl;
     963                 :          0 :                 num_to_refine++;
     964                 :            :             }
     965                 :            : 
     966                 :          0 :             if (tet_store.edge_store.get(key).lock_case == AMR::Edge_Lock_Case::unlocked)
     967                 :            :             {
     968                 :            :                 trace_out << "found unlocked" << std::endl;
     969                 :            :                 unlocked++;
     970                 :            :             }
     971                 :            : 
     972                 :          0 :             if (tet_store.edge_store.get(key).lock_case == AMR::Edge_Lock_Case::locked)
     973                 :            :             {
     974                 :            :                 trace_out << "found locked" << std::endl;
     975                 :            :                 locked++;
     976                 :            :             }
     977                 :            : 
     978                 :            :         }
     979                 :            : 
     980                 :            :         AMR::Refinement_State& element = tet_store.data(child_id);
     981                 :            : 
     982                 :            :         trace_out <<
     983                 :            :             "Intermediates " << num_intermediate <<
     984                 :            :             " num to refine " << num_to_refine <<
     985                 :            :             " unlocked " << unlocked <<
     986                 :            :             " locked " << locked <<
     987                 :            :             " Case " << element.refinement_case <<
     988                 :            :             std::endl;
     989                 :            : 
     990                 :            :         // check if element is 1:2
     991         [ -  - ]:          0 :         if (element.refinement_case == AMR::Refinement_Case::one_to_two)
     992                 :            :         {
     993                 :            :             // If so check it has 3 intermediates and 3 which need refining
     994         [ -  - ]:          0 :             if (num_intermediate != 3 || num_to_refine != 3) {
     995                 :          0 :                 return false;
     996                 :            :             }
     997                 :            :             else {
     998                 :            :                 trace_out << "True " <<
     999                 :            :                     "Intermediates " << num_intermediate <<
    1000                 :            :                     " num to refine " << num_to_refine <<
    1001                 :            :                     " Case " << element.refinement_case <<
    1002                 :            :                     " 2:1 " << AMR::Refinement_Case::one_to_two <<
    1003                 :            :                     std::endl;
    1004                 :            :             }
    1005                 :            :         }
    1006                 :            : 
    1007                 :            :         // check if element is 1:4
    1008         [ -  - ]:          0 :         else if (element.refinement_case == AMR::Refinement_Case::one_to_four)
    1009                 :            :         {
    1010                 :            :             // TODO: Check if it's a center tet for a 1:4
    1011                 :            :             // FIXME: Is this even needed? How else would you get these
    1012                 :            :             // combinations? Can't we just combine these two checks?
    1013                 :            : 
    1014                 :            :             bool is_center_tet = tet_store.is_center(child_id);
    1015                 :            : 
    1016                 :            :             if (is_center_tet)
    1017                 :            :             {
    1018         [ -  - ]:          0 :                 if (num_to_refine != 0 || num_intermediate != 6)
    1019                 :            :                 {
    1020                 :            :                     trace_out << "Fail compat 1:4 center" << std::endl;
    1021                 :          0 :                     return false;
    1022                 :            :                 }
    1023                 :            :             }
    1024                 :            :             else { // Is one of the outsides (not center)
    1025         [ -  - ]:          0 :                 if (num_to_refine != 1 || num_intermediate != 5)
    1026                 :            :                 {
    1027                 :            :                     trace_out << "Fail compat 1:4 non center" << std::endl;
    1028                 :          0 :                     return false;
    1029                 :            :                 }
    1030                 :            :             }
    1031                 :            :         }
    1032                 :            : 
    1033                 :            :         // If it makes it here, it's compatible
    1034                 :            :         return true;
    1035                 :            : 
    1036                 :            :     }
    1037                 :            : 
    1038                 :            :     /**
    1039                 :            :      * @brief Place holder method for the implementation of "Algorithm
    1040                 :            :      * 3" from the paper
    1041                 :            :      */
    1042                 :            :     // TODO: Does this parse a childs siblings multiple times?
    1043                 :          0 :     void mesh_adapter_t::refinement_class_three(size_t tet_id) {
    1044                 :            : 
    1045                 :            :         trace_out << "Refinement Class Three" << std::endl;
    1046                 :            : 
    1047                 :            :         // "Identify parent element iparent"
    1048                 :            :         // TODO: WE should either always use the id to fetch, or always do the data lookup
    1049                 :            :         //size_t parent_id = master_elements.get_parent(tet_id);
    1050                 :            :         size_t parent_id = tet_store.get_parent_id(tet_id);
    1051                 :            : 
    1052                 :            :         trace_out << "Parent id = " << parent_id << std::endl;
    1053                 :            : 
    1054                 :            :         // NOTE: This implies comms when we use these ids?
    1055                 :          0 :         child_id_list_t children = tet_store.data(parent_id).children;
    1056                 :            : 
    1057                 :            :         // "Do for each child element ielement
    1058                 :            :         // Activate all non-locked edges
    1059                 :            :         // Deactivate all locked edges"
    1060         [ -  - ]:          0 :         for (size_t i = 0; i < children.size(); i++)
    1061                 :            :         {
    1062                 :            :             // TODO: Is this in element or tet ids?
    1063                 :            :             trace_out << "Checking child " << children[i] << std::endl;
    1064         [ -  - ]:          0 :             edge_list_t edge_list = tet_store.generate_edge_keys(children[i]);
    1065         [ -  - ]:          0 :             for (size_t k = 0; k < NUM_TET_EDGES; k++)
    1066                 :            :             {
    1067                 :          0 :                 edge_t key = edge_list[k];
    1068                 :            :                 trace_out << "Compat 3 " << key << std::endl;
    1069 [ -  - ][ -  - ]:          0 :                 if (tet_store.edge_store.get(key).lock_case == AMR::Edge_Lock_Case::unlocked)
    1070                 :            :                 {
    1071                 :            :                     trace_out << "Compat 3 marking edge " << key << std::endl;
    1072                 :            :                     tet_store.edge_store.mark_for_refinement(key);
    1073                 :            :                 }
    1074                 :            :                 else {
    1075                 :            :                     tet_store.edge_store.unmark_for_refinement(key);
    1076                 :            :                 }
    1077                 :            :             }
    1078                 :            :         }
    1079                 :            : 
    1080                 :            :         // "Set compatible = TRUE
    1081                 :            :         bool compatible = true;
    1082                 :            : 
    1083                 :            :         // Do for each child element ielement
    1084                 :            :         // If ielement is not a valid refinement case
    1085                 :            :         // compatible = FALSE"
    1086         [ -  - ]:          0 :         for (size_t i = 0; i < children.size(); i++)
    1087                 :            :         {
    1088                 :          0 :             size_t child = children[i];
    1089 [ -  - ][ -  - ]:          0 :             if ( !check_valid_refinement_case(child) )
    1090                 :            :             {
    1091                 :            :                 trace_out << "Compat 3 Marking compatible false because of invalid refinement case" << std::endl;
    1092                 :            : 
    1093                 :            :                 compatible = false;
    1094                 :            :             }
    1095                 :            :             else {
    1096                 :            :                 trace_out << "Is compatible" << std::endl;
    1097                 :            :             }
    1098                 :            :         }
    1099                 :            : 
    1100                 :            :         // "If compatible = FALSE
    1101                 :            :         // Do for each child element ielement
    1102                 :            :         // Deactive all edges of ielement
    1103                 :            :         // Mark all edges of ielement as locked
    1104                 :            :         // Mark ielement as normal"
    1105         [ -  - ]:          0 :         if (compatible == false)
    1106                 :            :         {
    1107         [ -  - ]:          0 :             for (size_t i = 0; i < children.size(); i++)
    1108                 :            :             {
    1109                 :          0 :                 size_t child = children[i];
    1110         [ -  - ]:          0 :                 deactivate_tet_edges(child);
    1111         [ -  - ]:          0 :                 lock_tet_edges(child);
    1112                 :            :                 trace_out << "Compat 3 locking edges of " << child << std::endl;
    1113                 :            :                 // Here we interpret normal to mean "don't treat it like it has intermediates"
    1114                 :            :                 tet_store.mark_normal(child);
    1115                 :            :                 trace_out << "Compat 3 " << child << std::endl;
    1116                 :            :             }
    1117                 :            :         }
    1118                 :            :         else {
    1119                 :            :             trace_out << "TIME TO 2:8 " << tet_id << std::endl;
    1120                 :            :             // Accept as 2:8 or 4:8
    1121                 :            :             AMR::Refinement_State& element = tet_store.data(tet_id);
    1122         [ -  - ]:          0 :             if (element.refinement_case == AMR::Refinement_Case::one_to_two)
    1123                 :            :             {
    1124                 :            :                 tet_store.mark_two_to_eight(tet_id);
    1125                 :            :             }
    1126         [ -  - ]:          0 :             else if (element.refinement_case == AMR::Refinement_Case::one_to_four)
    1127                 :            :             {
    1128                 :            :                 tet_store.mark_four_to_eight(tet_id);
    1129                 :            :             }
    1130                 :            :             else {
    1131                 :            :                 trace_out << " I don't know what to do with this..it looks like you're trying to 2/4:8 an 8... " << std::endl;
    1132                 :            :             }
    1133                 :            : 
    1134                 :            :         }
    1135                 :          0 :     }
    1136                 :            : 
    1137                 :          0 :     void mesh_adapter_t::remove_normals()
    1138                 :            :     {
    1139         [ -  - ]:          0 :         for (const auto& kv : tet_store.tets)
    1140                 :            :         {
    1141                 :          0 :             size_t tet_id = kv.first;
    1142                 :            :             tet_store.set_normal(tet_id, 0);
    1143                 :            :         }
    1144                 :          0 :     }
    1145                 :            : 
    1146                 :          0 :     void mesh_adapter_t::remove_edge_locks(int intermediate)
    1147                 :            :     {
    1148         [ -  - ]:          0 :         for (const auto& kv : tet_store.tets)
    1149                 :            :         {
    1150                 :          0 :             size_t tet_id = kv.first;
    1151                 :            : 
    1152                 :            :             trace_out << "Process tet removelock " << tet_id << std::endl;
    1153                 :            : 
    1154                 :            :             // Only apply checks to tets on the active list
    1155                 :            :             if (tet_store.is_active(tet_id)) {
    1156                 :            :                 // change it from intermediate to locked
    1157                 :          0 :                 update_tet_edges_lock_type(tet_id, AMR::Edge_Lock_Case::locked, AMR::Edge_Lock_Case::unlocked);
    1158         [ -  - ]:          0 :                 if (intermediate) {
    1159                 :          0 :                     update_tet_edges_lock_type(tet_id, AMR::Edge_Lock_Case::intermediate, AMR::Edge_Lock_Case::unlocked);
    1160                 :            :                 }
    1161                 :            :             }
    1162                 :            :         }
    1163                 :            : 
    1164                 :          0 :     }
    1165                 :            :     //void mesh_adapter_t::reset_intermediate_edges()
    1166                 :            :     //{
    1167                 :            :     //    for (const auto& kv : tet_store.tets)
    1168                 :            :     //    {
    1169                 :            :     //        size_t tet_id = kv.first;
    1170                 :            : 
    1171                 :            :     //        trace_out << "Process tet reset " << tet_id << std::endl;
    1172                 :            : 
    1173                 :            :     //        // Only apply checks to tets on the active list
    1174                 :            :     //        if (tet_store.is_active(tet_id)) {
    1175                 :            :     //            // change it from intermediate to locked
    1176                 :            :     //            update_tet_edges_lock_type(tet_id, AMR::Edge_Lock_Case::intermediate, AMR::Edge_Lock_Case::locked);
    1177                 :            :     //        }
    1178                 :            :     //    }
    1179                 :            :     //}
    1180                 :            : 
    1181                 :          0 :     void mesh_adapter_t::update_tet_edges_lock_type(size_t tet_id, AMR::Edge_Lock_Case check, AMR::Edge_Lock_Case new_case) {
    1182                 :          0 :         edge_list_t edge_list = tet_store.generate_edge_keys(tet_id);
    1183         [ -  - ]:          0 :         for (size_t k = 0; k < NUM_TET_EDGES; k++)
    1184                 :            :         {
    1185                 :          0 :             edge_t key = edge_list[k];
    1186         [ -  - ]:          0 :             if (tet_store.edge_store.get(key).lock_case == check)
    1187                 :            :             {
    1188                 :          0 :                 tet_store.edge_store.get(key).lock_case = new_case;
    1189                 :            :             }
    1190                 :            :         }
    1191                 :          0 :     }
    1192                 :            : 
    1193                 :          0 :     void mesh_adapter_t::mark_derefinement()
    1194                 :            :     {
    1195                 :            :         const size_t max_num_rounds = AMR_MAX_ROUNDS;
    1196                 :            : 
    1197                 :            :         // Mark refinements
    1198                 :            :         size_t iter;
    1199                 :            :         //Iterate until convergence
    1200         [ -  - ]:          0 :         for (iter = 0; iter < max_num_rounds; iter++)
    1201                 :            :         {
    1202                 :          0 :             tet_store.marked_derefinements.get_state_changed() = false;
    1203                 :            : 
    1204                 :            :             // set of elements which have been considered for derefinement
    1205                 :            :             std::unordered_set< size_t > done_deref_marking;
    1206                 :            : 
    1207                 :            :             // Loop over tets
    1208         [ -  - ]:          0 :             for (const auto& kv : tet_store.tets)
    1209                 :            :             {
    1210                 :            :                 // this loop only runs for active tets
    1211                 :          0 :                 if (!tet_store.is_active(kv.first)) {
    1212         [ -  - ]:          0 :                   deactivate_deref_tet_edges(kv.first);
    1213                 :          0 :                   continue;
    1214                 :            :                 }
    1215                 :            :                 size_t activetet_id = kv.first;
    1216                 :            : 
    1217                 :            :                 // check if activetet_id has a parent (assign to tet_id)
    1218                 :            :                 // if it does not, activetet_id is not a derefinement candidate
    1219                 :            :                 size_t tet_id;
    1220                 :            :                 const auto& activetet_data = tet_store.data(activetet_id);
    1221         [ -  - ]:          0 :                 if (!activetet_data.has_parent) {
    1222         [ -  - ]:          0 :                   deactivate_deref_tet_edges(activetet_id);
    1223                 :          0 :                   continue;
    1224                 :            :                 }
    1225                 :            :                 else {
    1226                 :          0 :                   tet_id = activetet_data.parent_id;
    1227                 :            :                 }
    1228                 :            : 
    1229                 :            :                 // if already considered for deref, do not reconsider
    1230         [ -  - ]:          0 :                 if (done_deref_marking.count(tet_id) > 0) {
    1231                 :          0 :                   continue;
    1232                 :            :                 }
    1233                 :            :                 done_deref_marking.insert(tet_id);
    1234                 :            : 
    1235 [ -  - ][ -  - ]:          0 :                 child_id_list_t children = tet_store.data(tet_id).children;
    1236                 :            : 
    1237                 :            :                 // check if any child of tet_id (i.e. any active tet) is marked
    1238                 :            :                 // for refinement
    1239                 :            :                 bool is_child_ref(false);
    1240         [ -  - ]:          0 :                 for (size_t i=0; i<children.size(); i++) {
    1241         [ -  - ]:          0 :                   edge_list_t chedge_list = tet_store.generate_edge_keys(children[i]);
    1242                 :            :                   // Check each edge, see if it is marked for refinement
    1243         [ -  - ]:          0 :                   for (size_t k=0; k<NUM_TET_EDGES; k++) {
    1244                 :          0 :                     edge_t edge = chedge_list[k];
    1245                 :            : 
    1246 [ -  - ][ -  - ]:          0 :                     if (tet_store.edge_store.get(edge).needs_refining == 1) {
    1247                 :            :                       is_child_ref = true;
    1248                 :          0 :                       continue;
    1249                 :            :                     }
    1250                 :            :                   }
    1251                 :            :                 }
    1252                 :            :                 // deactivate from deref if marked for ref
    1253         [ -  - ]:          0 :                 if (is_child_ref) {
    1254         [ -  - ]:          0 :                   for (auto child_id : children) {
    1255         [ -  - ]:          0 :                     deactivate_deref_tet_edges(child_id);
    1256                 :            :                   }
    1257         [ -  - ]:          0 :                   deactivate_deref_tet_edges(tet_id);
    1258         [ -  - ]:          0 :                   continue;
    1259                 :            :                 }
    1260                 :            : 
    1261                 :            :                 // This is useful for later inspection
    1262                 :            :                 //edge_list_t edge_list = tet_store.generate_edge_keys(tet_id);
    1263                 :            :                 std::size_t num_to_derefine = 0; // Nodes
    1264                 :            : 
    1265         [ -  - ]:          0 :                 AMR::Refinement_Case refinement_case = tet_store.get_refinement_case(tet_id);
    1266                 :            : 
    1267         [ -  - ]:          0 :                 auto derefine_node_set = refiner.find_derefine_node_set(tet_store, tet_id);
    1268                 :            :                 // Find the set of nodes which are not in the parent
    1269                 :            :                 std::unordered_set<size_t> non_parent_nodes =
    1270         [ -  - ]:          0 :                   refiner.child_exclusive_nodes(tet_store, tet_id);
    1271                 :            : 
    1272                 :            :                 //for (auto drnode: derefine_node_set)
    1273                 :            :                 //  trace_out << "derefine node: " << drnode << std::endl;
    1274                 :            : 
    1275                 :            :                 num_to_derefine = derefine_node_set.size();
    1276                 :            : 
    1277                 :            :                 if (num_to_derefine > 0) {
    1278                 :            :                     trace_out << "num_to_derefine " << num_to_derefine << std::endl;
    1279                 :            :                     trace_out << "ref_case " << refinement_case << std::endl;
    1280                 :            :                     trace_out << "num children " << children.size() << std::endl;
    1281                 :            :                 }
    1282                 :            : 
    1283                 :            :                 //num_to_derefine = convert_derefine_edges_to_points(tet_store, tet_id, num_edges_to_derefine, refinement_case);
    1284                 :            : 
    1285                 :            :                 // "If nderefine = 1
    1286         [ -  - ]:          0 :                 if (num_to_derefine == 1)
    1287                 :            :                 {
    1288                 :            :                     // If icase = 1:2
    1289                 :            : 
    1290                 :            :                     //if (refinement_case == AMR::Refinement_Case::one_to_two)
    1291         [ -  - ]:          0 :                     if (children.size() == 2)
    1292                 :            :                     {
    1293                 :            :                         // Accept as 2:1 derefine"
    1294                 :            :                         trace_out << "Accept as 2:1" << std::endl;
    1295                 :            :                         //refiner.derefine_two_to_one(tet_store, node_connectivity, tet_id);
    1296         [ -  - ]:          0 :                         tet_store.mark_derefinement_decision(tet_id, AMR::Derefinement_Case::two_to_one);
    1297                 :            :                     }
    1298                 :            :                     // "Else
    1299                 :            :                     else {
    1300                 :            :                         // Deactivate all points"
    1301         [ -  - ]:          0 :                         for (auto child_id : children) {
    1302         [ -  - ]:          0 :                           deactivate_deref_tet_edges(child_id);
    1303                 :            :                         }
    1304         [ -  - ]:          0 :                         tet_store.mark_derefinement_decision(tet_id, AMR::Derefinement_Case::skip);
    1305                 :            :                         trace_out << "giving up on deref decision. deactivate near 2:1 ntd = 1" << std::endl;
    1306                 :            :                     }
    1307                 :            :                 }
    1308                 :            : 
    1309                 :            : 
    1310                 :            :                 // "If nderefine = 2
    1311         [ -  - ]:          0 :                 else if (num_to_derefine == 2)
    1312                 :            :                 {
    1313                 :            :                     // If icase = 1:4
    1314                 :            :                     //if (refinement_case == AMR::Refinement_Case::one_to_four)
    1315         [ -  - ]:          0 :                     if (children.size() == 4)
    1316                 :            :                     {
    1317                 :            :                         // Accept as 4:2 derefine"
    1318                 :            :                         trace_out << "Accept as 4:2" << std::endl;
    1319                 :            :                         //refiner.derefine_four_to_two(tet_store,  node_connectivity, tet_id);
    1320         [ -  - ]:          0 :                         tet_store.mark_derefinement_decision(tet_id, AMR::Derefinement_Case::four_to_two);
    1321                 :            :                     }
    1322                 :            :                     // "Else
    1323                 :            :                     else {
    1324                 :            :                         // Deactivate all points"
    1325         [ -  - ]:          0 :                         for (auto child_id : children) {
    1326         [ -  - ]:          0 :                           deactivate_deref_tet_edges(child_id);
    1327                 :            :                         }
    1328         [ -  - ]:          0 :                         tet_store.mark_derefinement_decision(tet_id, AMR::Derefinement_Case::skip);
    1329                 :            :                         trace_out << "giving up on deref decision. deactivate near 4:2 ntd = 2" << std::endl;
    1330                 :            :                     }
    1331                 :            :                 }
    1332                 :            : 
    1333                 :            :                 // "If nderefine = 3
    1334         [ -  - ]:          0 :                 else if (num_to_derefine == 3)
    1335                 :            :                 {
    1336                 :            :                     // If icase = 1:4
    1337                 :            :                     //if (refinement_case == AMR::Refinement_Case::one_to_four)
    1338         [ -  - ]:          0 :                     if (children.size() == 4)
    1339                 :            :                     {
    1340                 :            :                         // Accept as 4:1 derefine"
    1341                 :            :                         trace_out << "Accept as 4:1" << std::endl;
    1342                 :            :                         //refiner.derefine_four_to_one(tet_store,  node_connectivity, tet_id);
    1343         [ -  - ]:          0 :                         tet_store.mark_derefinement_decision(tet_id, AMR::Derefinement_Case::four_to_one);
    1344                 :            :                     }
    1345                 :            :                     // "Else if icase = 1:8
    1346                 :            :                     //else if (refinement_case == AMR::Refinement_Case::one_to_eight)
    1347         [ -  - ]:          0 :                     else if (children.size() == 8)
    1348                 :            :                     {
    1349                 :            :                         // we have a list of (non-parent) nodes that is marked
    1350                 :            :                         // for derefinement. First, determine the nodes that are
    1351                 :            :                         // unmarked for derefinement (or inactive_nodes). Then,
    1352                 :            :                         // determine if these are on a single face.
    1353                 :            :                         std::unordered_set<size_t> inactive_node_set;
    1354         [ -  - ]:          0 :                         for (auto npn : non_parent_nodes) {
    1355         [ -  - ]:          0 :                           if (derefine_node_set.count(npn) == 0)
    1356                 :            :                             inactive_node_set.insert(npn);
    1357                 :            :                         }
    1358                 :            :                         Assert(inactive_node_set.size() == 3, "Incorrectly "
    1359                 :            :                           "sized inactive-node set");
    1360         [ -  - ]:          0 :                         auto same_face = check_same_face(tet_id, inactive_node_set);
    1361                 :            :                         // If inactive points lie on same face
    1362         [ -  - ]:          0 :                         if (same_face.first == true)
    1363                 :            :                         {
    1364                 :            :                             // Accept as 8:4 derefinement
    1365                 :            :                             trace_out << "Accept as 8:4" << std::endl;
    1366                 :            : 
    1367                 :            :                             // create a vector of node-array-pairs to mark edges
    1368                 :            :                             // for refinement 1:4
    1369                 :            :                             std::vector< std::array< std::size_t, 2 > > ref_edges;
    1370         [ -  - ]:          0 :                             for (auto n:inactive_node_set) {
    1371                 :          0 :                               ref_edges.push_back(node_connectivity.get(n));
    1372                 :            :                             }
    1373                 :            : 
    1374 [ -  - ][ -  - ]:          0 :                             tet_store.edge_store.mark_edges_for_deref_ref(ref_edges);
                 [ -  - ]
    1375                 :            :                             //refiner.derefine_eight_to_four(tet_store,  node_connectivity, tet_id);
    1376         [ -  - ]:          0 :                             tet_store.mark_derefinement_decision(tet_id, AMR::Derefinement_Case::eight_to_four);
    1377                 :            :                         }
    1378                 :            :                         // "Else
    1379                 :            :                         else {
    1380                 :            :                             // Deactivate all points"
    1381         [ -  - ]:          0 :                             for (auto child_id : children) {
    1382         [ -  - ]:          0 :                               deactivate_deref_tet_edges(child_id);
    1383                 :            :                             }
    1384         [ -  - ]:          0 :                             tet_store.mark_derefinement_decision(tet_id, AMR::Derefinement_Case::skip);
    1385                 :            :                             trace_out << "giving up on deref decision. deactivate near 8:4 ntd = 3" << std::endl;
    1386                 :            :                         }
    1387                 :            : 
    1388                 :            :                     }
    1389                 :            :                 }
    1390                 :            : 
    1391                 :            :                 // "If nderefine = 4
    1392         [ -  - ]:          0 :                 else if (num_to_derefine == 4)
    1393                 :            :                 //else if (children.size() == 4)
    1394                 :            :                 {
    1395                 :            :                     // we have a list of (non-parent) nodes that is marked
    1396                 :            :                     // for derefinement. First, determine the nodes that are
    1397                 :            :                     // unmarked for derefinement (or inactive_nodes). Then,
    1398                 :            :                     // determine if these are on a single face.
    1399                 :            :                     std::unordered_set<size_t> inactive_node_set;
    1400         [ -  - ]:          0 :                     for (auto npn : non_parent_nodes) {
    1401         [ -  - ]:          0 :                       if (derefine_node_set.count(npn) == 0)
    1402                 :            :                         inactive_node_set.insert(npn);
    1403                 :            :                     }
    1404                 :            :                     Assert(inactive_node_set.size() == 2, "Incorrectly "
    1405                 :            :                       "sized inactive-node set");
    1406                 :            :                     // Check if the inactive point belong to the same parent
    1407                 :            :                     // face and deactivate the third point on that face
    1408         [ -  - ]:          0 :                     auto same_face = check_same_face(tet_id, inactive_node_set);
    1409                 :            : 
    1410         [ -  - ]:          0 :                     if (same_face.first == true)
    1411                 :            :                     {
    1412                 :            :                         // deactivate the edges associated with same_face.second
    1413         [ -  - ]:          0 :                         for (size_t i = 0; i < children.size(); i++)
    1414                 :            :                         {
    1415         [ -  - ]:          0 :                           edge_list_t edge_list = tet_store.generate_edge_keys(children[i]);
    1416         [ -  - ]:          0 :                           for (size_t k = 0; k < NUM_TET_EDGES; k++)
    1417                 :            :                           {
    1418                 :          0 :                             edge_t edge = edge_list[k];
    1419                 :            :                             size_t A = edge.first();
    1420                 :            :                             size_t B = edge.second();
    1421 [ -  - ][ -  - ]:          0 :                             if (A == same_face.second || B == same_face.second)
    1422         [ -  - ]:          0 :                               tet_store.edge_store.get(edge).needs_derefining = false;
    1423                 :            :                           }
    1424                 :            :                         }
    1425                 :            : 
    1426                 :            :                         // create a vector of node-array-pairs to mark edges
    1427                 :            :                         // for refinement 1:4
    1428                 :            :                         inactive_node_set.insert(same_face.second);
    1429                 :            :                         std::vector< std::array< std::size_t, 2 > > ref_edges;
    1430         [ -  - ]:          0 :                         for (auto n:inactive_node_set) {
    1431                 :          0 :                           ref_edges.push_back(node_connectivity.get(n));
    1432                 :            :                         }
    1433                 :            : 
    1434 [ -  - ][ -  - ]:          0 :                         tet_store.edge_store.mark_edges_for_deref_ref(ref_edges);
                 [ -  - ]
    1435                 :            : 
    1436                 :            :                         // Accept as 8:4 derefinement
    1437                 :            :                         trace_out << "Accept as 8:4" << std::endl;
    1438                 :            :                         //refiner.derefine_eight_to_four(tet_store,  node_connectivity, tet_id);
    1439         [ -  - ]:          0 :                         tet_store.mark_derefinement_decision(tet_id, AMR::Derefinement_Case::eight_to_four);
    1440                 :            :                     }
    1441                 :            :                     // "Else
    1442                 :            :                     else {
    1443                 :            :                         // Deactivate all points"
    1444         [ -  - ]:          0 :                         for (auto child_id : children) {
    1445         [ -  - ]:          0 :                           deactivate_deref_tet_edges(child_id);
    1446                 :            :                         }
    1447         [ -  - ]:          0 :                         tet_store.mark_derefinement_decision(tet_id, AMR::Derefinement_Case::skip);
    1448                 :            :                         trace_out << "giving up on deref decision. deactivate near 8:4 ntd = 4" << std::endl;
    1449                 :            :                     }
    1450                 :            :                 }
    1451                 :            : 
    1452                 :            :                 // "If nderefine = 5
    1453         [ -  - ]:          0 :                 else if (num_to_derefine == 5)
    1454                 :            :                 {
    1455                 :            :                     // Accept as 8:2 derefine"
    1456                 :            :                     trace_out << "Accept as 8:2 " << std::endl;
    1457                 :            :                     //refiner.derefine_eight_to_two(tet_store,  node_connectivity, tet_id);
    1458         [ -  - ]:          0 :                     tet_store.mark_derefinement_decision(tet_id, AMR::Derefinement_Case::eight_to_two);
    1459                 :            :                 }
    1460                 :            : 
    1461                 :            :                 // "If nderefine = 6
    1462         [ -  - ]:          0 :                 else if (num_to_derefine == 6)
    1463                 :            :                 {
    1464                 :            :                     // Accept as 8:1 derefine"
    1465                 :            :                     trace_out << "Accept as 8:1" << std::endl;
    1466                 :            :                     //refiner.derefine_eight_to_one(tet_store,  node_connectivity, tet_id);
    1467         [ -  - ]:          0 :                     tet_store.mark_derefinement_decision(tet_id, AMR::Derefinement_Case::eight_to_one);
    1468                 :            :                 }
    1469                 :            : 
    1470                 :            :                 // "If nderefine = 0
    1471                 :            :                 else {
    1472         [ -  - ]:          0 :                     tet_store.mark_derefinement_decision(tet_id, AMR::Derefinement_Case::skip);
    1473                 :            :                     // Deactivate all points"
    1474         [ -  - ]:          0 :                     for (auto child_id : children) {
    1475         [ -  - ]:          0 :                       deactivate_deref_tet_edges(child_id);
    1476                 :            :                     }
    1477                 :            :                     trace_out << "giving up with no deref decision because nderefine = 0" << std::endl;
    1478                 :            :                 }
    1479                 :            :             }
    1480                 :            : 
    1481                 :            :             // If nothing changed during that round, break
    1482         [ -  - ]:          0 :             if (!tet_store.marked_derefinements.get_state_changed())
    1483                 :            :             {
    1484                 :            :                 trace_out << "Terminating loop at iter " << iter << std::endl;
    1485                 :            :                 break;
    1486                 :            :             }
    1487                 :            :             trace_out << "End iter " << iter << std::endl;
    1488                 :            :             // clear out set of elements considered during this iteration
    1489                 :            :             done_deref_marking.clear();
    1490                 :            :         }
    1491                 :            :         trace_out << "Deref Loop took " << iter << " rounds." << std::endl;
    1492                 :          0 :     }
    1493                 :            : 
    1494                 :            :     // TODO: document
    1495                 :          0 :     void mesh_adapter_t::perform_derefinement()
    1496                 :            :     {
    1497                 :            :         trace_out << "Perform deref" << std::endl;
    1498                 :            : 
    1499                 :            :         // Do derefinements
    1500         [ -  - ]:          0 :         for (const auto& kv : tet_store.tets)
    1501                 :            :         {
    1502                 :          0 :             size_t tet_id = kv.first;
    1503                 :            :             //size_t parent_id = 0;
    1504                 :            : 
    1505                 :            :             // TODO: Do I really want to loop all tets?
    1506                 :            : 
    1507                 :            :             // TODO: is this doing a double lookup?
    1508                 :            :             if (tet_store.has_derefinement_decision(tet_id))
    1509                 :            :             {
    1510                 :            :                 trace_out << "Do derefine of " << tet_id << std::endl;
    1511                 :            :                 //size_t parent_id = tet_store.get_parent_id(tet_id);
    1512                 :            :                 //trace_out << "Parent = " << parent_id << std::endl;
    1513 [ -  - ][ -  - ]:          0 :                 switch(tet_store.marked_derefinements.get(tet_id))
            [ -  - ][ - ]
    1514                 :            :                 {
    1515                 :          0 :                     case AMR::Derefinement_Case::two_to_one:
    1516                 :          0 :                         refiner.derefine_two_to_one(tet_store,node_connectivity,tet_id);
    1517                 :            :                         trace_out << "Completed derefine 2:1 of " << tet_id << std::endl;
    1518                 :            :                         break;
    1519                 :          0 :                     case AMR::Derefinement_Case::four_to_one:
    1520                 :          0 :                         refiner.derefine_four_to_one(tet_store,node_connectivity,tet_id);
    1521                 :            :                         trace_out << "Completed derefine 4:1 of " << tet_id << std::endl;
    1522                 :            :                         break;
    1523                 :          0 :                     case AMR::Derefinement_Case::four_to_two:
    1524                 :          0 :                         refiner.derefine_four_to_two(tet_store,node_connectivity,tet_id);
    1525                 :            :                         trace_out << "Completed derefine 4:2 of " << tet_id << std::endl;
    1526                 :            :                         break;
    1527                 :          0 :                     case AMR::Derefinement_Case::eight_to_one:
    1528                 :          0 :                         refiner.derefine_eight_to_one(tet_store,node_connectivity,tet_id);
    1529                 :            :                         trace_out << "Completed derefine 8:1 of " << tet_id << std::endl;
    1530                 :            :                         break;
    1531                 :          0 :                     case AMR::Derefinement_Case::eight_to_two:
    1532                 :          0 :                         refiner.derefine_eight_to_two(tet_store,node_connectivity,tet_id);
    1533                 :            :                         trace_out << "Completed derefine 8:2 of " << tet_id << std::endl;
    1534                 :            :                         break;
    1535                 :          0 :                     case AMR::Derefinement_Case::eight_to_four:
    1536                 :          0 :                         refiner.derefine_eight_to_four(tet_store,node_connectivity,tet_id);
    1537                 :            :                         trace_out << "Completed derefine 8:4 of " << tet_id << std::endl;
    1538                 :            :                         break;
    1539                 :            :                     case AMR::Derefinement_Case::skip:
    1540                 :            :                         // What do we do with skip?
    1541                 :            :                         break;
    1542                 :            :                 }
    1543                 :            :                 // Mark tet as not needing derefinement
    1544                 :          0 :                 tet_store.marked_derefinements.erase(tet_id);
    1545                 :            :             }
    1546                 :            :         }
    1547                 :            : 
    1548                 :            :         node_connectivity.print();
    1549                 :          0 :         refiner.delete_intermediates_of_children(tet_store);
    1550                 :          0 :         tet_store.process_delete_list();
    1551                 :          0 :         tet_store.print_node_types();
    1552                 :            : 
    1553         [ -  - ]:          0 :         for (auto& kv : tet_store.edge_store.edges) {
    1554                 :            :            auto& local = kv.second;
    1555                 :          0 :            local.needs_derefining = 0;
    1556                 :            :         }
    1557                 :          0 :     }
    1558                 :            : 
    1559                 :            : }
    1560                 :            : 
    1561                 :            : #if defined(__clang__)
    1562                 :            :   #pragma clang diagnostic pop
    1563                 :            : #endif

Generated by: LCOV version 1.14