LCOV - code coverage report
Current view: top level - include/mesh - simplex_refiner.h (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4229 (6a9aeb) with base 727f46 Lines: 0 1 0.0 %
Date: 2025-08-19 19:27:09 Functions: 0 1 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // The libMesh Finite Element Library.
       2             : // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
       3             : 
       4             : // This library is free software; you can redistribute it and/or
       5             : // modify it under the terms of the GNU Lesser General Public
       6             : // License as published by the Free Software Foundation; either
       7             : // version 2.1 of the License, or (at your option) any later version.
       8             : 
       9             : // This library is distributed in the hope that it will be useful,
      10             : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12             : // Lesser General Public License for more details.
      13             : 
      14             : // You should have received a copy of the GNU Lesser General Public
      15             : // License along with this library; if not, write to the Free Software
      16             : // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
      17             : 
      18             : 
      19             : #ifndef LIBMESH_SIMPLEX_REFINER_H
      20             : #define LIBMESH_SIMPLEX_REFINER_H
      21             : 
      22             : #include "libmesh/libmesh_config.h"
      23             : 
      24             : // Local Includes
      25             : #include "libmesh/elem.h"
      26             : #include "libmesh/function_base.h"
      27             : 
      28             : #include <map>
      29             : #include <memory>
      30             : #include <tuple>
      31             : #include <unordered_map>
      32             : #include <utility>
      33             : #include <vector>
      34             : 
      35             : namespace libMesh
      36             : {
      37             : 
      38             : // Forward Declarations
      39             : class UnstructuredMesh;
      40             : class Node;
      41             : 
      42             : /**
      43             :  * A C++ class to refine a simplicial mesh via splitting edges that
      44             :  * exceed a given metric.
      45             :  *
      46             :  * \author Roy H. Stogner
      47             :  * \date 2024
      48             :  */
      49             : class SimplexRefiner
      50             : {
      51             : public:
      52             :   /**
      53             :    * The constructor.  A reference to the mesh containing the elements
      54             :    * which are to be split by edge subdivision must be provided.
      55             :    *
      56             :    * At the time of refining this mesh should be conforming.
      57             :    */
      58             :   explicit
      59             :   SimplexRefiner(UnstructuredMesh & mesh);
      60             : 
      61             :   /**
      62             :    * Finds elements which exceed the requested metric and refines them
      63             :    * via subdivision into new simplices as necessary.
      64             :    *
      65             :    * \returns \p true iff the mesh actually changed.
      66             :    */
      67             :   bool refine_elements ();
      68             : 
      69             :   /**
      70             :    * Set a function giving desired element volume as a function of
      71             :    * position.  Set this to nullptr to disable position-dependent volume
      72             :    * constraint (falling back on desired_volume()).
      73             :    */
      74             :   virtual void set_desired_volume_function (FunctionBase<Real> * desired);
      75             : 
      76             :   /**
      77             :    * Get the function giving desired element volume as a function of
      78             :    * position, or \p nullptr if no such function has been set.
      79             :    */
      80             :   virtual FunctionBase<Real> * get_desired_volume_function ();
      81             : 
      82             :   /**
      83             :    * Sets and/or gets the desired element volume. Set to zero to disable
      84             :    * volume constraint.
      85             :    *
      86             :    * If a \p desired_volume_function is set, then \p desired_volume()
      87             :    * should be used to set a *minimum* desired volume; this will reduce
      88             :    * "false negatives" by suggesting how finely to sample \p
      89             :    * desired_volume_function inside large elements, where ideally the
      90             :    * \p desired_volume_function will be satisfied in the element
      91             :    * interior and not just at the element vertices.
      92             :    */
      93           0 :   Real & desired_volume() {return _desired_volume;}
      94             : 
      95             : protected:
      96             : 
      97             :   /**
      98             :    * Finds elements which exceed the requested metric and refines them
      99             :    * via inserting new midedge nodes and bisecting as necessary.
     100             :    *
     101             :    * \returns the number of refined elements
     102             :    */
     103             :   std::size_t refine_via_edges();
     104             : 
     105             :   /**
     106             :    * Checks if an element exceeds the requested metric
     107             :    */
     108             :   bool should_refine_elem(Elem & elem);
     109             : 
     110             :   /**
     111             :    * Checks if an element exceeds the requested metric or if it
     112             :    * has an edge which was split by a neighboring metric and refines
     113             :    * it (bisecting it, removing it from the mesh to be replaced by the
     114             :    * two subelements, and recursing into those) if necessary.
     115             :    *
     116             :    * The \p coarse_id specifies which coarse element this one is (or
     117             :    * which this one was originally refined from), to make global
     118             :    * communication easier after local refinement is done.
     119             :    *
     120             :    * \returns the number of refinements done; this may be greater than
     121             :    * 1 if subelements were themselves refined.
     122             :    */
     123             : 
     124             :   std::size_t refine_via_edges(Elem & elem,
     125             :                                dof_id_type coarse_id);
     126             : 
     127             : private:
     128             : 
     129             :   /**
     130             :    * Reference to the mesh which is to be refined.
     131             :    */
     132             :   UnstructuredMesh & _mesh;
     133             : 
     134             :   /**
     135             :    * The desired volume for the elements in the resulting mesh.
     136             :    */
     137             :   Real _desired_volume;
     138             : 
     139             :   /**
     140             :    * Location-dependent volume requirements
     141             :    */
     142             :   std::unique_ptr<FunctionBase<Real>> _desired_volume_func;
     143             : 
     144             :   /**
     145             :    * Keep track of new nodes on edges.  A new node x in between node y
     146             :    * and node z (with y<z) will be reflected by new_nodes[(y,z)]=x
     147             :    */
     148             :   std::map<std::pair<Node *, Node *>, Node *> new_nodes;
     149             : 
     150             :   /**
     151             :    * Keep track of elements to add so we don't invalidate iterators
     152             :    * during an iteration over elements.
     153             :    */
     154             :   std::vector<std::unique_ptr<Elem>> new_elements;
     155             : 
     156             :   /**
     157             :    * Keep track of coarse remote edges for which we should query about
     158             :    * additional point splits
     159             :    */
     160             :   std::unordered_map
     161             :     <processor_id_type,
     162             :      std::vector<std::pair<dof_id_type, dof_id_type>>>
     163             :     edge_queries;
     164             : 
     165             :   // All the "refine first and second to get third" that was
     166             :   // done to this edge, including the processor to assign the new node
     167             :   // to.
     168             :   typedef
     169             :     std::vector<std::tuple<dof_id_type, dof_id_type,
     170             :                            dof_id_type, processor_id_type>>
     171             :     refinement_datum;
     172             : 
     173             :   /**
     174             :    * Helper for responding to edge queries
     175             :    */
     176             :   void fill_refinement_datum(std::pair<Node *, Node *> vertices,
     177             :                              refinement_datum & vec);
     178             : 
     179             :   /**
     180             :    * Keep track of elements added within each original element, so we
     181             :    * can answer queries about them from other processors.  If the
     182             :    * element originally with id i is split, its replacements e1 and e2
     183             :    * will be in added_elements[i][ei.vertex_average()]
     184             :    */
     185             :   std::unordered_map<dof_id_type, std::unordered_map<Point, Elem *>> added_elements;
     186             : 
     187             :   /**
     188             :    * Keep track of added elements' original coarse ids, so we get
     189             :    * subsequent splits assigned to the correct coarse id.
     190             :    */
     191             :   std::unordered_map<Elem *, dof_id_type> coarse_parent;
     192             : 
     193             :   /**
     194             :    * Keep track of what processor an element's neighbors came from
     195             :    */
     196             :   std::unordered_map<processor_id_type, std::unique_ptr<Elem>> proxy_elements;
     197             : };
     198             : 
     199             : 
     200             : } // namespace libMesh
     201             : 
     202             : #endif // ifndef LIBMESH_SIMPLEX_REFINER_H

Generated by: LCOV version 1.14