Xyst test code coverage report
Current view: top level - Inciter - Refiner.hpp (source / functions) Hit Total Coverage
Commit: e489e3468f2b950872163df1285c13fa7a355e8c Lines: 46 46 100.0 %
Date: 2024-11-20 18:16:45 Functions: 3 3 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 8 10 80.0 %

           Branch data     Line data    Source code
       1                 :            : // *****************************************************************************
       2                 :            : /*!
       3                 :            :   \file      src/Inciter/Refiner.hpp
       4                 :            :   \copyright 2012-2015 J. Bakosi,
       5                 :            :              2016-2018 Los Alamos National Security, LLC.,
       6                 :            :              2019-2021 Triad National Security, LLC.,
       7                 :            :              2022-2024 J. Bakosi
       8                 :            :              All rights reserved. See the LICENSE file for details.
       9                 :            :   \brief     Mesh refiner for interfacing the mesh refinement library
      10                 :            :   \details   Mesh refiner is a Charm++ chare array and is used to interface the
      11                 :            :    mesh refinement object which does not know about parallelization and thus the
      12                 :            :    distributed nature of the mesh it operates on, i.e., it operates on mesh
      13                 :            :    chunks. Thus it does not do parallel communication and also does not know
      14                 :            :    about global vs local IDs. Instead this Charm++ chare array is the one that
      15                 :            :    does all parallel computing aspects, i.e., communcation, and using the mesh
      16                 :            :    refiner object as a library.
      17                 :            : */
      18                 :            : // *****************************************************************************
      19                 :            : #pragma once
      20                 :            : 
      21                 :            : #include <vector>
      22                 :            : #include <unordered_map>
      23                 :            : 
      24                 :            : #include "PUPAMR.hpp"
      25                 :            : #include "AMR/mesh_adapter.hpp"
      26                 :            : #include "TaggedTuple.hpp"
      27                 :            : #include "Callback.hpp"
      28                 :            : #include "UnsMesh.hpp"
      29                 :            : #include "Base/Fields.hpp"
      30                 :            : #include "RieCG.hpp"
      31                 :            : #include "LaxCG.hpp"
      32                 :            : #include "ZalCG.hpp"
      33                 :            : #include "KozCG.hpp"
      34                 :            : #include "ChoCG.hpp"
      35                 :            : #include "LohCG.hpp"
      36                 :            : 
      37                 :            : #include "NoWarning/transporter.decl.h"
      38                 :            : #include "NoWarning/refiner.decl.h"
      39                 :            : 
      40                 :            : namespace inciter {
      41                 :            : 
      42                 :            : //! Mesh refiner for interfacing the mesh refinement library
      43                 :            : class Refiner : public CBase_Refiner {
      44                 :            : 
      45                 :            :   private:
      46                 :            :     using Edge = tk::UnsMesh::Edge;
      47                 :            :     using Face = tk::UnsMesh::Face;
      48                 :            :     using Tet = tk::UnsMesh::Tet;
      49                 :            :     using EdgeSet = tk::UnsMesh::EdgeSet;
      50                 :            :     using FaceSet = tk::UnsMesh::FaceSet;
      51                 :            :     using TetSet = tk::UnsMesh::TetSet;
      52                 :            :     template< std::size_t N > using Hash = tk::UnsMesh::Hash< N >;
      53                 :            :     template< std::size_t N > using Eq = tk::UnsMesh::Eq< N >;
      54                 :            : 
      55                 :            :     //! Boundary face data, see boundary()
      56                 :            :     using BndFaceData = std::unordered_map< Face, std::size_t, Hash<3>, Eq<3> >;
      57                 :            : 
      58                 :            :     //! Used to associate error to edges
      59                 :            :     using EdgeError = std::unordered_map< Edge, tk::real, Hash<2>, Eq<2> >;
      60                 :            : 
      61                 :            :   public:
      62                 :            :     //! Mode of operation: the way Refiner is used
      63                 :            :     enum class RefMode : std::size_t {
      64                 :            :         T0REF = 1        //!< Initial (t<0) refinement
      65                 :            :       , DTREF            //!< During time stepping (t>0)
      66                 :            :     };
      67                 :            : 
      68                 :            :     //! Constructor
      69                 :            :     explicit Refiner( std::size_t meshid,
      70                 :            :                       const CProxy_Transporter& transporter,
      71                 :            :                       const CProxy_Sorter& sorter,
      72                 :            :                       const tk::CProxy_MeshWriter& meshwriter,
      73                 :            :                       const CProxy_Discretization& discretization,
      74                 :            :                       const CProxy_RieCG& riecg,
      75                 :            :                       const CProxy_LaxCG& laxcg,
      76                 :            :                       const CProxy_ZalCG& zalcg,
      77                 :            :                       const CProxy_KozCG& kozcg,
      78                 :            :                       const CProxy_ChoCG& chocg,
      79                 :            :                       const CProxy_LohCG& lohcg,
      80                 :            :                       const tk::CProxy_ConjugateGradients& cgpre,
      81                 :            :                       const tk::CProxy_ConjugateGradients& cgmom,
      82                 :            :                       const tk::RefinerCallback& cbr,
      83                 :            :                       const tk::SorterCallback& cbs,
      84                 :            :                       const std::vector< std::size_t >& ginpoel,
      85                 :            :                       const tk::UnsMesh::CoordMap& coordmap,
      86                 :            :                       const std::map< int, std::vector< std::size_t > >& bface,
      87                 :            :                       const std::vector< std::size_t >& triinpoel,
      88                 :            :                       const std::map< int, std::vector< std::size_t > >& bnode,
      89                 :            :                       int nchare );
      90                 :            : 
      91                 :            :     #if defined(__clang__)
      92                 :            :       #pragma clang diagnostic push
      93                 :            :       #pragma clang diagnostic ignored "-Wundefined-func-template"
      94                 :            :     #endif
      95                 :            :     //! Migrate constructor
      96                 :            :     // cppcheck-suppress uninitMemberVar
      97                 :       9988 :     explicit Refiner( CkMigrateMessage* m ) : CBase_Refiner( m ) {}
      98                 :            :     #if defined(__clang__)
      99                 :            :       #pragma clang diagnostic pop
     100                 :            :     #endif
     101                 :            : 
     102                 :            :     //! \brief Incoming query for a list boundary edges for which this chare
     103                 :            :     //!   compiles shared edges
     104                 :            :     void query( int fromch, const EdgeSet& edges );
     105                 :            :     //! Receive receipt of boundary edge lists to quer
     106                 :            :     void recvquery();
     107                 :            :     //! Respond to boundary edge list queries
     108                 :            :     void response();
     109                 :            :     //! Receive shared boundary edges for our mesh chunk
     110                 :            :     void bnd( int fromch, const std::vector< int >& chares );
     111                 :            :     //! Receive receipt of shared boundary edges
     112                 :            :     void recvbnd();
     113                 :            : 
     114                 :            :     //! Query Sorter and update local mesh with the reordered one
     115                 :            :     void reorder();
     116                 :            : 
     117                 :            :     //! Start new step of initial mesh refinement/derefinement
     118                 :            :     void start();
     119                 :            : 
     120                 :            :     //! Continue after finishing a refinemen/derefinementt step
     121                 :            :     void next();
     122                 :            : 
     123                 :            :     //! Start mesh refinement (during time stepping, t>0)
     124                 :            :     void dtref( const std::map< int, std::vector< std::size_t > >& bface,
     125                 :            :                 const std::map< int, std::vector< std::size_t > >& bnode,
     126                 :            :                 const std::vector< std::size_t >& triinpoel );
     127                 :            : 
     128                 :            :     //! Do a single step of mesh refinemen/derefinementt (only tag edges)
     129                 :            :     void refine();
     130                 :            : 
     131                 :            :     //! Receive newly added mesh edges and locks on our chare boundary
     132                 :            :     void addRefBndEdges( int fromch,
     133                 :            :                          const AMR::EdgeData& ed,
     134                 :            :                          const std::unordered_set<size_t>& intermediates );
     135                 :            : 
     136                 :            :     //! Correct refinement to arrive at conforming mesh across chare boundaries
     137                 :            :     void correctref();
     138                 :            : 
     139                 :            :     //! Communicate refined edges after a refinement/derefinement step
     140                 :            :     void comExtra();
     141                 :            : 
     142                 :            :     //! Perform mesh refinement and decide how to continue
     143                 :            :     void perform();
     144                 :            : 
     145                 :            :     //! Send Refiner proxy to Discretization objects
     146                 :            :     void sendProxy();
     147                 :            : 
     148                 :            :     //! Get refinement field data in mesh cells
     149                 :            :     std::tuple< std::vector< std::string >,
     150                 :            :                 std::vector< std::vector< tk::real > >,
     151                 :            :                 std::vector< std::string >,
     152                 :            :                 std::vector< std::vector< tk::real > > >
     153                 :            :     refinementFields() const;
     154                 :            : 
     155                 :            :     /** @name Charm++ pack/unpack serializer member functions */
     156                 :            :     ///@{
     157                 :            :     //! \brief Pack/Unpack serialize member function
     158                 :            :     //! \param[in,out] p Charm++'s PUP::er serializer object reference
     159                 :      15664 :     void pup( PUP::er &p ) override {
     160                 :      15664 :       p | m_meshid;
     161                 :      15664 :       p | m_ncit;
     162                 :            :       p | m_host;
     163                 :            :       p | m_sorter;
     164                 :            :       p | m_meshwriter;
     165                 :            :       p | m_disc;
     166                 :            :       p | m_riecg;
     167                 :            :       p | m_laxcg;
     168                 :            :       p | m_zalcg;
     169                 :            :       p | m_kozcg;
     170                 :            :       p | m_chocg;
     171                 :            :       p | m_lohcg;
     172                 :            :       p | m_cgpre;
     173                 :            :       p | m_cgmom;
     174                 :            :       p | m_cbr;
     175                 :            :       p | m_cbs;
     176                 :      15664 :       p | m_ginpoel;
     177                 :      15664 :       p | m_el;
     178         [ +  + ]:      15664 :       if (p.isUnpacking()) {
     179                 :       4994 :         m_inpoel = std::get< 0 >( m_el );
     180                 :       4994 :         m_gid = std::get< 1 >( m_el );
     181         [ -  + ]:       4994 :         m_lid = std::get< 2 >( m_el );
     182                 :            :       }
     183                 :      15664 :       p | m_coordmap;
     184                 :            :       p | m_coord;
     185                 :      15664 :       p | m_bface;
     186                 :      15664 :       p | m_bnode;
     187                 :      15664 :       p | m_triinpoel;
     188                 :      15664 :       p | m_nchare;
     189                 :      15664 :       p | m_mode;
     190                 :      15664 :       p | m_initref;
     191                 :      15664 :       p | m_refiner;
     192                 :      15664 :       p | m_nref;
     193                 :      15664 :       p | m_nbnd;
     194                 :      15664 :       p | m_extra;
     195                 :      15664 :       p | m_ch;
     196                 :      15664 :       p | m_edgech;
     197                 :      15664 :       p | m_chedge;
     198                 :      15664 :       p | m_localEdgeData;
     199                 :      15664 :       p | m_remoteEdgeData;
     200                 :      15664 :       p | m_remoteEdges;
     201                 :      15664 :       p | m_intermediates;
     202                 :      15664 :       p | m_nodeCommMap;
     203                 :      15664 :       p | m_oldTets;
     204                 :      15664 :       p | m_addedNodes;
     205                 :      15664 :       p | m_addedTets;
     206                 :      15664 :       p | m_removedNodes;
     207                 :      15664 :       p | m_amrNodeMap;
     208                 :      15664 :       p | m_oldntets;
     209                 :      15664 :       p | m_coarseBndFaces;
     210                 :      15664 :       p | m_coarseBndNodes;
     211                 :      15664 :       p | m_rid;
     212                 :            :       //p | m_oldrid;
     213                 :      15664 :       p | m_lref;
     214                 :            :       //p | m_oldlref;
     215                 :            :       //p | m_oldparent;
     216                 :      15664 :       p | m_writeCallback;
     217                 :      15664 :     }
     218                 :            :     //! \brief Pack/Unpack serialize operator|
     219                 :            :     //! \param[in,out] p Charm++'s PUP::er serializer object reference
     220                 :            :     //! \param[in,out] r Refiner object reference
     221                 :            :     friend void operator|( PUP::er& p, Refiner& r ) { r.pup(p); }
     222                 :            :     //@}
     223                 :            : 
     224                 :            :   private:
     225                 :            :     //! Mesh ID
     226                 :            :     std::size_t m_meshid;
     227                 :            :     //! Number of parallel-compatibility (mesh ref correction) iterations
     228                 :            :     std::size_t m_ncit;
     229                 :            :     //! Host proxy
     230                 :            :     CProxy_Transporter m_host;
     231                 :            :     //! Mesh sorter proxy
     232                 :            :     CProxy_Sorter m_sorter;
     233                 :            :     //! Mesh writer proxy
     234                 :            :     tk::CProxy_MeshWriter m_meshwriter;
     235                 :            :     //! Discretization base proxy
     236                 :            :     CProxy_Discretization m_disc;
     237                 :            :     //! Discretization scheme proxy
     238                 :            :     CProxy_RieCG m_riecg;
     239                 :            :     //! Discretization scheme proxy
     240                 :            :     CProxy_LaxCG m_laxcg;
     241                 :            :     //! Discretization scheme proxy
     242                 :            :     CProxy_ZalCG m_zalcg;
     243                 :            :     //! Discretization scheme proxy
     244                 :            :     CProxy_KozCG m_kozcg;
     245                 :            :     //! Discretization scheme proxy
     246                 :            :     CProxy_ChoCG m_chocg;
     247                 :            :     //! Discretization scheme proxy
     248                 :            :     CProxy_LohCG m_lohcg;
     249                 :            :     //! Conjugate Gradients Charm++ proxy for pressure solve
     250                 :            :     tk::CProxy_ConjugateGradients m_cgpre;
     251                 :            :     //! Conjugate Gradients Charm++ proxy for momentum solve
     252                 :            :     tk::CProxy_ConjugateGradients m_cgmom;
     253                 :            :     //! Charm++ callbacks associated to compile-time tags for refiner
     254                 :            :     tk::RefinerCallback m_cbr;
     255                 :            :     //! Charm++ callbacks associated to compile-time tags for sorter
     256                 :            :     tk::SorterCallback m_cbs;
     257                 :            :     //! Tetrtahedron element connectivity of our chunk of the mesh (global ids)
     258                 :            :     std::vector< std::size_t > m_ginpoel;
     259                 :            :     //! Elements of the mesh chunk we operate on
     260                 :            :     //! \details The first vector is the element connectivity (local IDs), the
     261                 :            :     //!   second vector is the global node IDs of owned elements, while the
     262                 :            :     //!   third one is a map of global->local node IDs.
     263                 :            :     tk::UnsMesh::Chunk m_el;
     264                 :            :     //! Alias to element connectivity with local node IDs in m_el
     265                 :            :     std::vector< std::size_t >& m_inpoel = std::get<0>( m_el );
     266                 :            :     //! Alias to global node IDs of owned elements in m_el
     267                 :            :     std::vector< std::size_t >& m_gid = std::get<1>( m_el );
     268                 :            :     //! \brief Alias to local node IDs associated to the global ones of owned
     269                 :            :     //!    elements in m_el
     270                 :            :     std::unordered_map< std::size_t, std::size_t >& m_lid = std::get<2>( m_el );
     271                 :            :     //! Coordinates associated to global node IDs of our mesh chunk
     272                 :            :     tk::UnsMesh::CoordMap m_coordmap;
     273                 :            :     //! Coordinates of mesh nodes of our chunk of the mesh
     274                 :            :     tk::UnsMesh::Coords m_coord;
     275                 :            :     //! List of boundary faces associated to side-set IDs
     276                 :            :     std::map< int, std::vector< std::size_t > > m_bface;
     277                 :            :     //! List of boundary nodes associated to side-set IDs
     278                 :            :     std::map< int, std::vector< std::size_t > > m_bnode;
     279                 :            :     //! Boundary face-node connectivity
     280                 :            :     std::vector< std::size_t > m_triinpoel;
     281                 :            :     //! Total number of refiner chares
     282                 :            :     int m_nchare;
     283                 :            :     //! True if initial AMR, false if during time stepping
     284                 :            :     RefMode m_mode;
     285                 :            :     //! Initial mesh refinement type list (in reverse order)
     286                 :            :     std::vector< std::string > m_initref;
     287                 :            :     //! Number of initial mesh refinement/derefinement steps
     288                 :            :     std::size_t m_ninitref;
     289                 :            :     //! Mesh refiner (library) object
     290                 :            :     AMR::mesh_adapter_t m_refiner;
     291                 :            :     //! Counter during distribution of newly added nodes to chare-boundary edges
     292                 :            :     std::size_t m_nref;
     293                 :            :     //! Counter for number of chares contributing to chare boundary edges
     294                 :            :     std::size_t m_nbnd;
     295                 :            :     //! Number of chare-boundary newly added nodes that need correction
     296                 :            :     std::size_t m_extra;
     297                 :            :     //! Chares we share at least a single edge with
     298                 :            :     std::unordered_set< int > m_ch;
     299                 :            :     //! Edge->chare map used to build shared boundary edges
     300                 :            :     std::unordered_map< Edge, std::vector< int >, Hash<2>, Eq<2> > m_edgech;
     301                 :            :     //! Chare->edge map used to build shared boundary edges
     302                 :            :     std::unordered_map< int, EdgeSet > m_chedge;
     303                 :            :     //! Refinement data associated to edges (edges stored with node-gids)
     304                 :            :     AMR::EdgeData m_localEdgeData;
     305                 :            :     //! \brief Refinement data associated to edges shared with other chares
     306                 :            :     //!   (edges stored with node-gids)
     307                 :            :     std::unordered_map< int, std::vector< std::tuple<
     308                 :            :       Edge, int, int, AMR::Edge_Lock_Case > > > m_remoteEdgeData;
     309                 :            :     //! Edges received from other chares
     310                 :            :     std::unordered_map< int, std::vector< Edge > > m_remoteEdges;
     311                 :            :     //! Intermediate nodes
     312                 :            :     std::unordered_set< size_t> m_intermediates;
     313                 :            :     //! \brief Global mesh node IDs bordering the mesh chunk held by fellow
     314                 :            :     //!    worker chares associated to their chare IDs for the coarse mesh
     315                 :            :     std::unordered_map< int, std::unordered_set< std::size_t > > m_nodeCommMap;
     316                 :            :     //! Tetrahedra before refinement/derefinement step
     317                 :            :     TetSet m_oldTets;
     318                 :            :     //! Newly added mesh nodes (local id) and their parents (local ids)
     319                 :            :     std::unordered_map< std::size_t, Edge > m_addedNodes;
     320                 :            :     //! Newly added mesh cells (local id) and their parent (local id)
     321                 :            :     std::unordered_map< std::size_t, std::size_t > m_addedTets;
     322                 :            :     //! Newly removed mesh node local ids
     323                 :            :     std::set< std::size_t > m_removedNodes;
     324                 :            :     //! Node id maps from old mesh to new refined mesh
     325                 :            :     std::unordered_map< std::size_t, std::size_t > m_amrNodeMap;
     326                 :            :     //! Number of tetrahedra in the mesh before refinement/derefinement step
     327                 :            :     std::size_t m_oldntets;
     328                 :            :     //! A unique set of faces associated to side sets of the coarsest mesh
     329                 :            :     std::unordered_map< int, FaceSet > m_coarseBndFaces;
     330                 :            :     //! A unique set of nodes associated to side sets of the coarsest mesh
     331                 :            :     std::unordered_map< int, std::unordered_set<std::size_t> > m_coarseBndNodes;
     332                 :            :     //! Local -> refiner lib node id map
     333                 :            :     std::vector< std::size_t > m_rid;
     334                 :            :     //! Local -> refiner lib node id map for previous mesh
     335                 :            :     //std::vector< std::size_t > m_oldrid;
     336                 :            :     //! Refiner lib -> local node id map
     337                 :            :     std::unordered_map< std::size_t, std::size_t > m_lref;
     338                 :            :     //! Refiner lib -> local node id map for previous mesh
     339                 :            :     //std::unordered_map< std::size_t, std::size_t > m_oldlref;
     340                 :            :     //! Child -> parent tet map for previous mesh
     341                 :            :     //std::unordered_map< Tet, Tet, Hash<4>, Eq<4> > m_oldparent;
     342                 :            :     //! Function to continue with after writing field output
     343                 :            :     CkCallback m_writeCallback;
     344                 :            : 
     345                 :            :     //! (Re-)generate local -> refiner lib node id map and its inverse
     346                 :            :     void libmap();
     347                 :            : 
     348                 :            :     //! (Re-)generate side set and block data structures for coarse mesh
     349                 :            :     void coarseMesh();
     350                 :            : 
     351                 :            :     //! Generate flat coordinate data from coordinate map
     352                 :            :     tk::UnsMesh::Coords flatcoord( const tk::UnsMesh::CoordMap& coordmap );
     353                 :            : 
     354                 :            :     //! Output mesh to file before a new step of mesh refinement/derefinement
     355                 :            :     void t0ref();
     356                 :            : 
     357                 :            :     //! Generate boundary edges and send them to all chares
     358                 :            :     void bndEdges();
     359                 :            : 
     360                 :            :     //! Finish initiel mesh refinement
     361                 :            :     void endt0ref();
     362                 :            : 
     363                 :            :     //! Do uniform mesh refinement
     364                 :            :     void uniformRefine();
     365                 :            : 
     366                 :            :     //! Do uniform mesh derefinement
     367                 :            :     void uniformDeRefine();
     368                 :            : 
     369                 :            :     //! Do error-based mesh refinement
     370                 :            :     void errorRefine();
     371                 :            : 
     372                 :            :     //! Compute errors in edges
     373                 :            :     EdgeError
     374                 :            :     errorsInEdges( std::size_t npoin,
     375                 :            :                    const std::pair< std::vector< std::size_t >,
     376                 :            :                                     std::vector< std::size_t > >& esup,
     377                 :            :                    const tk::Fields& u ) const;
     378                 :            : 
     379                 :            :     //! Update (or evaluate) solution on current mesh
     380                 :            :     tk::Fields
     381                 :            :     solution( std::size_t npoin,
     382                 :            :               const std::pair< std::vector< std::size_t >,
     383                 :            :                                std::vector< std::size_t > >& esup ) const;
     384                 :            : 
     385                 :            :     //! Do mesh refinement based on user explicitly tagging edges
     386                 :            :     void edgelistRefine();
     387                 :            : 
     388                 :            :     //! Do mesh refinement based on tagging edges based on end-point coordinates
     389                 :            :     void coordRefine();
     390                 :            : 
     391                 :            :     //! Query AMR lib and update our local store of edge data
     392                 :            :     void updateEdgeData();
     393                 :            : 
     394                 :            :     //! Query AMR lib and update our local store of boundary edge data
     395                 :            :     void updateBndEdgeData();
     396                 :            : 
     397                 :            :     //! Aggregate number of extra edges across all chares
     398                 :            :     void matched();
     399                 :            : 
     400                 :            :     //! Update old mesh after refinement
     401                 :            :     void updateMesh();
     402                 :            : 
     403                 :            :     //! Update volume mesh after mesh refinement
     404                 :            :     void newVolMesh( const std::unordered_set< std::size_t >& old,
     405                 :            :                      const std::unordered_set< std::size_t >& ref );
     406                 :            : 
     407                 :            :     //! Update boundary data structures after mesh refinement
     408                 :            :     void newBndMesh( const std::unordered_set< std::size_t >& ref );
     409                 :            : 
     410                 :            :     //! \brief Generate boundary data structures used to update
     411                 :            :     //!   refined/derefined boundary faces and nodes of side sets
     412                 :            :     BndFaceData boundary();
     413                 :            : 
     414                 :            :     //! Regenerate boundary faces and nodes after AMR step
     415                 :            :     void updateBndData( const std::unordered_set< std::size_t >& ref,
     416                 :            :                         const BndFaceData& pcFaceTets );
     417                 :            : 
     418                 :            :     //! Evaluate initial conditions (IC) at mesh nodes
     419                 :            :     tk::Fields
     420                 :            :     nodeinit( std::size_t /*npoin*/,
     421                 :            :               const std::pair< std::vector< std::size_t >,
     422                 :            :                                std::vector< std::size_t > >& /*esup*/ ) const;
     423                 :            : 
     424                 :            :     //! Output mesh to file(s)
     425                 :            :     void writeMesh( const std::string& basefilename,
     426                 :            :                     uint64_t it,
     427                 :            :                     tk::real t,
     428                 :            :                     CkCallback c ) const;
     429                 :            : 
     430                 :            :     //! Compute partial boundary surface integral and sum across all chares
     431                 :            :     bool bndIntegral();
     432                 :            : 
     433                 :            :     //! Find the oldest parents of a mesh node in the AMR hierarchy
     434                 :            :     std::unordered_set< std::size_t >
     435                 :            :     ancestors( std::size_t n );
     436                 :            : 
     437                 :            :     //! Return a set of keys among whose values a primitive is found
     438                 :            :     //! \tparam Sets Type of map of sets we search for the primitive
     439                 :            :     //! \tparam Primitive The primitive we search for in the sets
     440                 :            :     //! \note Sets::mapped_type == Primitive
     441                 :            :     //! \param[in] sets Map of sets we search in
     442                 :            :     //! \param[in] p Primitive we search for
     443                 :            :     //! \return A unique set of set ids in which the primitive is found or
     444                 :            :     //!   an empty set if the primitive was not found.
     445                 :            :     //! \details This function searches a map of sets for an item (a primitive,
     446                 :            :     //!   e.g., a single id or a face given by 3 node ids) and returns a
     447                 :            :     //!   unique set of keys behind whose associated sets the item was found.
     448                 :            :     template< class Sets, class Primitive >
     449                 :            :     std::unordered_set< int >
     450                 :    1161854 :     keys( const Sets& sets, const Primitive& p ) {
     451                 :            :       static_assert( std::is_same< typename Sets::mapped_type::value_type,
     452                 :            :         Primitive >::value, "Type of primitive (face/node) in map of sets must "
     453                 :            :         "be the same as the type of primitive (face/node) that is searched" );
     454                 :            :       std::unordered_set< int > ss;
     455         [ +  + ]:    7275024 :       for (const auto& s : sets)
     456         [ +  + ]:    6113170 :         if (s.second.find(p) != end(s.second))
     457         [ +  - ]:    1725540 :           ss.insert( s.first );
     458                 :    1161854 :       return ss;
     459                 :            :     }
     460                 :            : };
     461                 :            : 
     462                 :            : } // inciter::

Generated by: LCOV version 1.16