LCOV - code coverage report
Current view: top level - ext/amrex/3d-coverage-g++-24.08/include - AMReX_Geometry.H (source / functions) Hit Total Coverage
Test: coverage_merged.info Lines: 9 14 64.3 %
Date: 2024-11-18 05:28:54 Functions: 6 9 66.7 %

          Line data    Source code
       1             : #ifndef AMREX_GEOMETRY_H_
       2             : #define AMREX_GEOMETRY_H_
       3             : #include <AMReX_Config.H>
       4             : 
       5             : #include <AMReX_Array.H>
       6             : #include <AMReX_CoordSys.H>
       7             : #include <AMReX_ParallelDescriptor.H>
       8             : #include <AMReX_RealBox.H>
       9             : #include <AMReX_Periodicity.H>
      10             : 
      11             : #ifdef AMREX_USE_OMP
      12             : #include <omp.h>
      13             : #endif
      14             : 
      15             : #include <iosfwd>
      16             : #include <map>
      17             : 
      18             : namespace amrex {
      19             : 
      20             : class MultiFab;
      21             : class DistributionMapping;
      22             : class BoxArray;
      23             : 
      24             : struct GeometryData
      25             : {
      26             :  //! Returns the cellsize for each coordinate direction.
      27             :     [[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
      28             :     const Real* CellSize () const noexcept { return dx; }
      29             :     //
      30             :     [[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
      31             :     Real CellSize (int dir) const noexcept { return dx[dir]; }
      32             :  //! Returns the lo end of the problem domain in each dimension.
      33             :     [[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
      34             :     const Real* ProbLo () const noexcept { return prob_domain.lo(); }
      35             :     //
      36             :     [[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
      37             :     Real ProbLo (int dir) const noexcept { return prob_domain.lo(dir); }
      38             :  //! Returns the hi end of the problem domain in each dimension.
      39             :     [[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
      40             :     const Real* ProbHi () const noexcept { return prob_domain.hi(); }
      41             :     //
      42             :     [[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
      43             :     Real ProbHi (int dir) const noexcept { return prob_domain.hi(dir); }
      44             :  //! Returns our rectangular domain.
      45             :     [[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
      46             :     const Box& Domain () const noexcept { return domain; }
      47             : //! Returns whether the domain is periodic in the given direction.
      48             :     [[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
      49             :     int isPeriodic (const int i) const noexcept { return is_periodic[i]; }
      50             :  //! Coordinates type
      51             :     [[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
      52             :     int Coord () const noexcept { return coord; }
      53             : 
      54             : public:
      55             :     RealBox prob_domain;
      56             :     Box domain;
      57             :     Real dx[AMREX_SPACEDIM];
      58             :     int is_periodic[AMREX_SPACEDIM]; /**< For each dimension, 0 if the domain is non-periodic and 1 if it is. */
      59             :     int coord;
      60             : };
      61             : 
      62             : /**
      63             :  * \class Geometry
      64             :  * \brief Rectangular problem domain geometry.
      65             :  *
      66             :  * This class describes problem domain and coordinate system for
      67             :  * RECTANGULAR problem domains.  Since the problem domain is RECTANGULAR,
      68             :  * periodicity is meaningful.
      69             :  */
      70             : class Geometry
      71             :     :
      72             :     public CoordSys
      73             : {
      74             : public:
      75             :     /** \brief The default constructor.
      76             :      *
      77             :      *   Leaves object in an unusable state. A "define" method must be called before use.
      78             :      */
      79             :     Geometry () noexcept;
      80             : 
      81             :     /**
      82             :      * Constructs a fully-defined geometry object that describes the problem domain and coordinate system.
      83             :      *
      84             :      * \param dom cell-centered `Box` specifying the index space bounds of the domain.
      85             :      * \param rb A pointer to a `RealBox` specifying the real space bounds of the domain. Optional. If not specified,
      86             :      *        will be ParmParsed from "geometry.prob_lo" and "geometry.prob_hi".
      87             :      * \param coord Specifies the coordinate system type. Optional. Can be one of:
      88             :      *        CoordSys::cartesian
      89             :      *        CoordSys::RZ
      90             :      *        CoordSys::SPHERICAL
      91             :      *        Default is cartesian.
      92             :      * \param is_per pointer to memory space specifying periodicity in each coordinate direction.
      93             :      *        Optional. Default is non-periodic.
      94             :      */
      95             :     explicit Geometry (const Box&     dom,
      96             :                        const RealBox* rb     =  nullptr,
      97             :                        int            coord  = -1,
      98             :                        int const*     is_per =  nullptr) noexcept;
      99             :     /**
     100             :      * Constructs a fully-defined geometry object that describes the problem domain and coordinate system.
     101             :      *
     102             :      * \param dom cell-centered `Box` specifying the index space bounds of the domain.
     103             :      * \param rb A pointer to a `RealBox` specifying the real space bounds of the domain. Optional. If not specified,
     104             :      *        will be ParmParsed from "geometry.prob_lo" and "geometry.prob_hi".
     105             :      * \param coord Specifies the coordinate system type. Optional. Can be one of:
     106             :      *        CoordSys::cartesian
     107             :      *        CoordSys::RZ
     108             :      *        CoordSys::SPHERICAL
     109             :      *        Default is cartesian.
     110             :      * \param is_per amrex::Array specifying periodicity in each coordinate direction. Optional.
     111             :      *        Default is non-periodic.
     112             :      */
     113             :     Geometry (const Box& dom, const RealBox& rb, int coord,
     114             :               Array<int,AMREX_SPACEDIM> const& is_per) noexcept;
     115             : 
     116             :     ~Geometry () = default;
     117             :     Geometry (const Geometry& rhs) = default;
     118             :     Geometry (Geometry&& rhs) noexcept = default;
     119             :     Geometry& operator= (const Geometry& rhs) = default;
     120             :     Geometry& operator= (Geometry&& rhs) noexcept = default;
     121             : 
     122             :     //! Returns non-static copy of geometry's stored data.
     123             :     [[nodiscard]] GeometryData data() const noexcept {
     124             :         return { prob_domain, domain, {AMREX_D_DECL(dx[0],dx[1],dx[2])},
     125             :             {AMREX_D_DECL(is_periodic[0], is_periodic[1], is_periodic[2])},
     126             :                 static_cast<int>(c_sys) };
     127             :     }
     128             : 
     129             :     //! Read static values from ParmParse database.
     130             :     static void Setup (const RealBox* rb = nullptr, int coord = -1, int const* isper = nullptr) noexcept;
     131             :     static void ResetDefaultProbDomain (const RealBox& rb) noexcept;
     132             :     static void ResetDefaultPeriodicity (const Array<int,AMREX_SPACEDIM>& is_per) noexcept;
     133             :     static void ResetDefaultCoord (int coord) noexcept;
     134             : 
     135             :     /**
     136             :      * Defines a geometry object that describes the problem domain and coordinate system for rectangular problem
     137             :      * domains. Useful for when the Geometry object has been constructed with the default constructor.
     138             :      *
     139             :      * \param dom cell-centered `Box` specifying the index space bounds of the domain.
     140             :      * \param rb A pointer to a `RealBox` specifying the real space bounds of the domain. Optional. If not specified,
     141             :      *        will be ParmParsed from "geometry.prob_lo" and "geometry.prob_hi".
     142             :      * \param coord Specifies the coordinate system type. Optional. Can be one of:
     143             :      *        CoordSys::cartesian
     144             :      *        CoordSys::RZ
     145             :      *        CoordSys::SPHERICAL
     146             :      *        Default is cartesian.
     147             :      * \param is_per pointer to memory space specifying periodicity in each coordinate direction.
     148             :      *        Optional. Default is non-periodic.
     149             :      */
     150             :     void define (const Box& dom, const RealBox* rb = nullptr, int coord = -1, int const* is_per = nullptr) noexcept;
     151             : 
     152             :     /**
     153             :      * Defines a geometry object that describes the problem domain and coordinate system for rectangular problem
     154             :      * domains. Useful for when the Geometry object has been constructed with the default constructor.
     155             :      *
     156             :      * \param dom cell-centered `Box` specifying the index space bounds of the domain.
     157             :      * \param rb A pointer to a `RealBox` specifying the real space bounds of the domain. Optional. If not specified,
     158             :      *        will be ParmParsed from "geometry.prob_lo" and "geometry.prob_hi".
     159             :      * \param coord Specifies the coordinate system type. Optional. Can be one of:
     160             :      *        CoordSys::cartesian
     161             :      *        CoordSys::RZ
     162             :      *        CoordSys::SPHERICAL
     163             :      *        Default is cartesian.
     164             :      * \param is_per amrex::Array specifying periodicity in each coordinate direction. Optional.
     165             :      *        Default is non-periodic.
     166             :      */
     167             :     void define (const Box& dom, const RealBox& rb, int coord, Array<int,AMREX_SPACEDIM> const& is_per) noexcept;
     168             : 
     169             :     //! Returns the problem domain.
     170             :     [[nodiscard]] const RealBox& ProbDomain () const noexcept { return prob_domain; }
     171             :     //! Sets the problem domain.
     172             :     void ProbDomain (const RealBox& rb) noexcept
     173             :     {
     174             :         prob_domain = rb;
     175             :         computeRoundoffDomain();
     176             :     }
     177             :     //! Returns the lo end of the problem domain in each dimension.
     178     7458230 :     [[nodiscard]] const Real* ProbLo () const noexcept { return prob_domain.lo(); }
     179             :     //! Returns the hi end of the problem domain in each dimension.
     180          78 :     [[nodiscard]] const Real* ProbHi () const noexcept { return prob_domain.hi(); }
     181             :     //! Returns the lo end of the problem domain in specified direction.
     182           0 :     [[nodiscard]] Real ProbLo (int dir) const noexcept { return prob_domain.lo(dir); }
     183             :     //! Returns the hi end of the problem domain in specified direction.
     184           0 :     [[nodiscard]] Real ProbHi (int dir) const noexcept { return prob_domain.hi(dir); }
     185             : 
     186             :     [[nodiscard]] GpuArray<Real,AMREX_SPACEDIM> ProbLoArray () const noexcept {
     187             :         return {{AMREX_D_DECL(prob_domain.lo(0),prob_domain.lo(1),prob_domain.lo(2))}};
     188             :     }
     189             : 
     190             :     [[nodiscard]] GpuArray<Real,AMREX_SPACEDIM> ProbHiArray () const noexcept {
     191             :         return {{AMREX_D_DECL(prob_domain.hi(0),prob_domain.hi(1),prob_domain.hi(2))}};
     192             :     }
     193             : 
     194             :     [[nodiscard]] GpuArray<ParticleReal,AMREX_SPACEDIM> ProbLoArrayInParticleReal () const noexcept {
     195             :         return roundoff_lo;
     196             :     }
     197             : 
     198             :     [[nodiscard]] GpuArray<ParticleReal,AMREX_SPACEDIM> ProbHiArrayInParticleReal () const noexcept {
     199             :         return roundoff_hi;
     200             :     }
     201             : 
     202             :     //! Returns the overall size of the domain by multiplying the ProbLength's together
     203             :     [[nodiscard]] Real ProbSize () const noexcept
     204             :     {
     205             :         return AMREX_D_TERM(prob_domain.length(0),*prob_domain.length(1),*prob_domain.length(2));
     206             :     }
     207             :     //! Returns length of problem domain in specified dimension.
     208             :     [[nodiscard]] Real ProbLength (int dir) const noexcept { return prob_domain.length(dir); }
     209             :     //! Returns our rectangular domain.
     210      397983 :     [[nodiscard]] const Box& Domain () const noexcept { return domain; }
     211             :     //! Sets our rectangular domain.
     212             :     void Domain (const Box& bx) noexcept
     213             :     {
     214             :         AMREX_ASSERT(bx.cellCentered());
     215             :         domain = bx;
     216             :         computeRoundoffDomain();
     217             :     }
     218             :     //! Define a multifab of areas and volumes with given grow factor.
     219             :     void GetVolume (MultiFab&       vol,
     220             :                     const BoxArray& grds,
     221             :                     const DistributionMapping& dm,
     222             :                     int             grow) const;
     223             :     //! Fill the pre-built multifab with volume
     224             :     void GetVolume (MultiFab&       vol) const;
     225             : 
     226             :     void GetVolume (FArrayBox&      vol,
     227             :                     const BoxArray& grds,
     228             :                     int             idx,
     229             :                     int             grow) const;
     230             : 
     231             :     //! Return the volume of the specified cell.
     232             :     AMREX_GPU_HOST_DEVICE AMREX_INLINE
     233             :     static Real Volume (const IntVect& point, const GeometryData& geomdata)
     234             :     {
     235             :         const auto *dx = geomdata.CellSize();
     236             : 
     237             :         Real vol;
     238             : 
     239             : #if AMREX_SPACEDIM == 1
     240             : 
     241             :         auto coord = geomdata.Coord();
     242             : 
     243             :         if (coord == CoordSys::cartesian) {
     244             :             // Cartesian
     245             : 
     246             :             vol = dx[0];
     247             :         }
     248             :         else {
     249             :             // Spherical
     250             : 
     251             :             Real rl = geomdata.ProbLo()[0] + static_cast<Real>(point[0]) * dx[0];
     252             :             Real rr = rl + dx[0];
     253             : 
     254             :             constexpr Real pi = Real(3.1415926535897932);
     255             :             vol = (4.0_rt / 3.0_rt) * pi * dx[0] * (rl * rl + rl * rr + rr * rr);
     256             :         }
     257             : 
     258             : #elif AMREX_SPACEDIM == 2
     259             : 
     260             :         auto coord = geomdata.Coord();
     261             : 
     262             :         if (coord == CoordSys::cartesian) {
     263             :             // Cartesian
     264             : 
     265             :             vol = dx[0] * dx[1];
     266             :         }
     267             :         else {
     268             :             // Cylindrical
     269             : 
     270             :             Real r_l = geomdata.ProbLo()[0] + static_cast<Real>(point[0]) * dx[0];
     271             :             Real r_r = geomdata.ProbLo()[0] + static_cast<Real>(point[0]+1) * dx[0];
     272             : 
     273             :             constexpr Real pi = Real(3.1415926535897932);
     274             :             vol = pi * (r_l + r_r) * dx[0] * dx[1];
     275             :         }
     276             : 
     277             : #else
     278             : 
     279             :         amrex::ignore_unused(point);
     280             : 
     281             :         // Cartesian
     282             : 
     283             :         vol = dx[0] * dx[1] * dx[2];
     284             : 
     285             : #endif
     286             : 
     287             :         return vol;
     288             :     }
     289             : 
     290             :     /**
     291             :     * \brief Compute d(log(A))/dr at cell centers in given region and
     292             :     *           stuff the results into the passed MultiFab.
     293             :     */
     294             :     void GetDLogA (MultiFab&       dloga,
     295             :                    const BoxArray& grds,
     296             :                    const DistributionMapping& dm,
     297             :                    int             dir,
     298             :                    int             grow) const;
     299             :     /**
     300             :     * \brief Compute area of cell faces in given region and stuff
     301             :     * stuff the results into the passed MultiFab.
     302             :     */
     303             :     void GetFaceArea (MultiFab&       area,
     304             :                       const BoxArray& grds,
     305             :                       const DistributionMapping& dm,
     306             :                       int             dir,
     307             :                       int             grow) const;
     308             :     //! Fill the pre-built multifab with area
     309             :     void GetFaceArea (MultiFab&       area,
     310             :                       int             dir) const;
     311             : 
     312             :     void GetFaceArea (FArrayBox&      area,
     313             :                       const BoxArray& grds,
     314             :                       int             idx,
     315             :                       int             dir,
     316             :                       int             grow) const;
     317             :     //! Is the domain periodic in the specified direction?
     318        1098 :     [[nodiscard]] bool isPeriodic (int dir) const noexcept { return is_periodic[dir]; }
     319             :     //! Is domain periodic in any direction?
     320         300 :     [[nodiscard]] bool isAnyPeriodic () const noexcept
     321             :     {
     322         300 :         return AMREX_D_TERM(isPeriodic(0),||isPeriodic(1),||isPeriodic(2));
     323             :     }
     324             :     //! Is domain periodic in all directions?
     325             :     [[nodiscard]] bool isAllPeriodic ()  const noexcept
     326             :     {
     327             :         return AMREX_D_TERM(isPeriodic(0),&&isPeriodic(1),&&isPeriodic(2));
     328             :     }
     329             :     [[nodiscard]] Array<int,AMREX_SPACEDIM> isPeriodic () const noexcept {
     330             :         return {{AMREX_D_DECL(static_cast<int>(is_periodic[0]),
     331             :                               static_cast<int>(is_periodic[1]),
     332             :                               static_cast<int>(is_periodic[2]))}};
     333             :     }
     334             :     [[nodiscard]] GpuArray<int,AMREX_SPACEDIM> isPeriodicArray () const noexcept {
     335             :         return {{AMREX_D_DECL(static_cast<int>(is_periodic[0]),
     336             :                               static_cast<int>(is_periodic[1]),
     337             :                               static_cast<int>(is_periodic[2]))}};
     338             :     }
     339             :     //! What's period in specified direction?
     340             :     [[nodiscard]] int period (int dir) const noexcept { BL_ASSERT(is_periodic[dir]); return domain.length(dir); }
     341             : 
     342       10184 :     [[nodiscard]] Periodicity periodicity () const noexcept {
     343       10184 :         return Periodicity(IntVect(AMREX_D_DECL(domain.length(0) * is_periodic[0],
     344             :                                           domain.length(1) * is_periodic[1],
     345       10184 :                                           domain.length(2) * is_periodic[2])));
     346             :     }
     347             : 
     348           0 :     [[nodiscard]] Periodicity periodicity (const Box& b) const noexcept {
     349             :         AMREX_ASSERT(b.cellCentered());
     350           0 :         return Periodicity(IntVect(AMREX_D_DECL(b.length(0) * is_periodic[0],
     351             :                                                 b.length(1) * is_periodic[1],
     352           0 :                                                 b.length(2) * is_periodic[2])));
     353             :     }
     354             : 
     355             :     /**
     356             :     * \brief Compute Array of shifts which will translate src so that it will
     357             :     * intersect target with non-zero intersection.  the array will be
     358             :     * resized internally, so anything previously there will be gone
     359             :     * DO NOT return non-periodic shifts, even if the box's do
     360             :     * intersect without shifting.  The logic is that you will only do
     361             :     * this as a special case if there is some periodicity.
     362             :     */
     363             :     void periodicShift (const Box&      target,
     364             :                         const Box&      src,
     365             :                         Vector<IntVect>& out) const noexcept;
     366             : 
     367             :     //! Return domain box with non-periodic directions grown by ngrow.
     368             :     [[nodiscard]] Box growNonPeriodicDomain (IntVect const& ngrow) const noexcept;
     369             :     //! Return domain box with non-periodic directions grown by ngrow.
     370             :     [[nodiscard]] Box growNonPeriodicDomain (int ngrow) const noexcept;
     371             :     //! Return domain box with periodic directions grown by ngrow.
     372             :     [[nodiscard]] Box growPeriodicDomain (IntVect const& ngrow) const noexcept;
     373             :     //! Return domain box with periodic directions grown by ngrow.
     374             :     [[nodiscard]] Box growPeriodicDomain (int ngrow) const noexcept;
     375             : 
     376             :     //! Set periodicity flags and return the old flags.
     377             :     //! Note that, unlike Periodicity class, the flags are just boolean.
     378             :     //!
     379             :     Array<int,AMREX_SPACEDIM>
     380             :     setPeriodicity (Array<int,AMREX_SPACEDIM> const& period) noexcept {
     381             :         Array<int,AMREX_SPACEDIM> r{{AMREX_D_DECL(is_periodic[0],
     382             :                                                   is_periodic[1],
     383             :                                                   is_periodic[2])}};
     384             :         AMREX_D_TERM(is_periodic[0] = period[0];,
     385             :                      is_periodic[1] = period[1];,
     386             :                      is_periodic[2] = period[2];);
     387             :         return r;
     388             :     }
     389             : 
     390             :     void coarsen (IntVect const& rr) {
     391             :         domain.coarsen(rr);
     392             :         for (int i = 0; i < AMREX_SPACEDIM; ++i) {
     393             :             dx[i] = (ProbHi(i) - ProbLo(i)) / static_cast<Real>(domain.length(i));
     394             :             inv_dx[i] = Real(1.)/dx[i];
     395             :         }
     396             :     }
     397             : 
     398             :     void refine (IntVect const& rr) {
     399             :         domain.refine(rr);
     400             :         for (int i = 0; i < AMREX_SPACEDIM; ++i) {
     401             :             dx[i] = (ProbHi(i) - ProbLo(i)) / static_cast<Real>(domain.length(i));
     402             :             inv_dx[i] = Real(1.)/dx[i];
     403             :         }
     404             :     }
     405             : 
     406             :     /**
     407             :     * \brief Returns true if a point is outside the roundoff domain.
     408             :     *        All particles with positions inside the roundoff domain
     409             :     *        are sure to be mapped to cells inside the Domain() box. Note that
     410             :     *        the same need not be true for all points inside ProbDomain().
     411             :     */
     412             :     [[nodiscard]] bool outsideRoundoffDomain (AMREX_D_DECL(ParticleReal x, ParticleReal y, ParticleReal z)) const;
     413             : 
     414             :     /**
     415             :     * \brief Returns true if a point is inside the roundoff domain.
     416             :     *        All particles with positions inside the roundoff domain
     417             :     *        are sure to be mapped to cells inside the Domain() box. Note that
     418             :     *        the same need not be true for all points inside ProbDomain().
     419             :     */
     420             :     [[nodiscard]] bool insideRoundoffDomain (AMREX_D_DECL(ParticleReal x, ParticleReal y, ParticleReal z)) const;
     421             : 
     422             :     /**
     423             :     * \brief Compute the roundoff domain. Public because it contains an
     424             :     *        extended host / device lambda.
     425             :     */
     426             :     void computeRoundoffDomain ();
     427             : 
     428             : private:
     429             :     void read_params ();
     430             : 
     431             :     // is_periodic and RealBox used to be static
     432             :     bool    is_periodic[AMREX_SPACEDIM] = {AMREX_D_DECL(false,false,false)};
     433             :     RealBox prob_domain;
     434             : 
     435             :     // Due to round-off errors, not all floating point numbers for which plo >= x < phi
     436             :     // will map to a cell that is inside "domain". "roundoff_{lo,hi}" store
     437             :     // positions that are very close to that in prob_domain, and for which all doubles and floats
     438             :     // between them will map to a cell inside domain.
     439             :     GpuArray<ParticleReal , AMREX_SPACEDIM> roundoff_lo, roundoff_hi;
     440             : 
     441             :     //
     442             :     Box     domain;
     443             : 
     444             :     friend std::istream& operator>> (std::istream&, Geometry&);
     445             : };
     446             : 
     447             : 
     448             : //! Nice ASCII output.
     449             : std::ostream& operator<< (std::ostream&, const Geometry&);
     450             : //! Nice ASCII input.
     451             : std::istream& operator>> (std::istream&, Geometry&);
     452             : 
     453             : inline
     454             : Geometry
     455             : coarsen (Geometry const& fine, IntVect const& rr) {
     456             :     Geometry r{fine};
     457             :     r.coarsen(rr);
     458             :     return r;
     459             : }
     460             : 
     461             : inline
     462             : Geometry
     463             : coarsen (Geometry const& fine, int rr) { return coarsen(fine, IntVect(rr)); }
     464             : 
     465             : inline
     466             : Geometry
     467             : refine (Geometry const& crse, IntVect const& rr) {
     468             :     Geometry r{crse};
     469             :     r.refine(rr);
     470             :     return r;
     471             : }
     472             : 
     473             : inline
     474             : Geometry
     475             : refine (Geometry const& crse, int rr) { return refine(crse, IntVect(rr)); }
     476             : 
     477             : inline
     478             : const Geometry&
     479             : DefaultGeometry () {
     480             :     return *(AMReX::top()->getDefaultGeometry());
     481             : }
     482             : 
     483             : }
     484             : 
     485             : #endif /*_GEOMETRY_H_*/

Generated by: LCOV version 1.14