LCOV - code coverage report
Current view: top level - src/Integrator - BaseField.H (source / functions) Coverage Total Hit
Test: coverage_merged.info Lines: 73.5 % 132 97
Test Date: 2025-02-27 04:17:48 Functions: 40.4 % 470 190

            Line data    Source code
       1              : #ifndef INTEGRATOR_BASEFIELD_H
       2              : #define INTEGRATOR_BASEFIELD_H
       3              : 
       4              : #include "AMReX_FillPatchUtil.H"
       5              : 
       6              : #include "Util/Util.H"
       7              : #include "Set/Set.H"
       8              : #include "Numeric/Interpolator/NodeBilinear.H"
       9              : 
      10              : namespace Integrator
      11              : {
      12              : 
      13              : class BaseField
      14              : {
      15              : public:
      16           98 :     virtual ~BaseField() = default;
      17              : 
      18              :     virtual void RemakeLevel (int lev,       
      19              :                             amrex::Real time, 
      20              :                             const amrex::BoxArray& cgrids, 
      21              :                             const amrex::DistributionMapping& dm) = 0;
      22              :     virtual void MakeNewLevelFromCoarse (int lev, 
      23              :                                         amrex::Real time, 
      24              :                                         const amrex::BoxArray& cgrids, 
      25              :                                         const amrex::DistributionMapping& dm) = 0;
      26              :     virtual void MakeNewLevelFromScratch (int lev, 
      27              :                                         amrex::Real t, 
      28              :                                         const amrex::BoxArray& cgrids,
      29              :                                         const amrex::DistributionMapping& dm) = 0;
      30              :     virtual void SetFinestLevel(const int a_finestlevel) = 0;
      31              :     virtual void FillPatch(const int lev, const Set::Scalar time)=0;
      32              :     virtual void FillBoundary(const int lev, Set::Scalar time)=0;
      33              :     virtual void AverageDown(const int lev, amrex::IntVect refRatio) = 0;
      34              : 
      35              :     virtual int NComp() = 0;
      36              :     virtual void Copy(int /*a_lev*/, amrex::MultiFab &/*a_dst*/, int /*a_dstcomp*/, int /*a_nghost*/) = 0;
      37              :     bool writeout = false;
      38              :     virtual std::string Name(int) = 0;
      39              :     virtual void setName(std::string a_name) = 0;
      40              :     bool evolving = true;
      41              :     virtual void setBC(void * a_bc) = 0;
      42              :     virtual void * getBC() = 0;
      43              :     Set::Hypercube m_gridtype;
      44              : };
      45              : 
      46              : template<class T>
      47              : class Field : public BaseField
      48              : {
      49              : public:
      50              :     class EmptyBC
      51              :     {
      52              :     public:
      53        45349 :         virtual void operator () (amrex::FabArray<amrex::BaseFab<T>> & /*mf*/, 
      54              :                                 int /*dcomp*/, int /*ncomp*/, amrex::IntVect const& /*nghost*/, 
      55              :                                 amrex::Real /*time*/, int /*bccomp*/) 
      56        45349 :         {  /* Do nothing - this is a shell to satisfy the FillPatch functions.*/   }
      57        13028 :         amrex::BCRec GetBCRec() {return amrex::BCRec();}
      58              :     };
      59              : 
      60          272 :     Field(Set::Field<T> & a_field, 
      61              :         const amrex::Vector<amrex::Geometry> &a_geom, 
      62              :         const amrex::Vector<amrex::IntVect> &a_refRatio,
      63              :         int a_ncomp, int a_nghost) : 
      64          272 :         m_field(a_field), m_geom(a_geom), m_refRatio(a_refRatio), 
      65          272 :         m_ncomp(a_ncomp), m_nghost(a_nghost)
      66          272 :     {} 
      67              :     
      68              :     void 
      69        42051 :     FillPatch (int lev, amrex::Real time,
      70              :                 amrex::Vector<std::unique_ptr<amrex::FabArray<amrex::BaseFab<T>>>> &source_mf,
      71              :                 amrex::FabArray<amrex::BaseFab<T>> &destination_mf, 
      72              :                 int icomp)
      73              :     {
      74        42051 :         EmptyBC physbc;
      75        42051 :         if (lev == 0)
      76              :         {
      77        38836 :             amrex::Vector<amrex::FabArray<amrex::BaseFab<T>>*> smf;
      78        38836 :             smf.push_back(source_mf[lev].get());
      79        38836 :             amrex::Vector<amrex::Real> stime;
      80        38836 :             stime.push_back(time);
      81              : 
      82        38836 :             if (m_gridtype == Set::Hypercube::Cell)
      83              :             {
      84            0 :                 m_bc->define(m_geom[lev]);
      85            0 :                 amrex::FillPatchSingleLevel(destination_mf, time, smf, stime,
      86            0 :                                             0, icomp, destination_mf.nComp(), m_geom[lev],
      87            0 :                                             *m_bc, 0);
      88              :             }
      89        38836 :             else if (m_gridtype == Set::Hypercube::Node)
      90              :             {
      91        38836 :                 amrex::FillPatchSingleLevel(destination_mf, time, smf, stime,
      92        38836 :                                 0, icomp, destination_mf.nComp(), m_geom[lev],
      93              :                                 physbc, 0);
      94              :             }
      95        38836 :         } 
      96              :         else
      97              :         {
      98         3215 :             amrex::Vector<amrex::FabArray<amrex::BaseFab<T>>*> cmf, fmf;
      99         3215 :             cmf.push_back(source_mf[lev-1].get());
     100         3215 :             fmf.push_back(source_mf[lev].get());
     101         3215 :             amrex::Vector<amrex::Real> ctime, ftime;
     102         3215 :             ctime.push_back(time);
     103         3215 :             ftime.push_back(time);
     104              : 
     105         3215 :             amrex::Vector<amrex::BCRec> bcs(destination_mf.nComp(), physbc.GetBCRec()); 
     106              : 
     107         6430 :             if (destination_mf.boxArray().ixType() == amrex::IndexType::TheNodeType())
     108              :             {
     109         3215 :                 amrex::FillPatchTwoLevels(destination_mf, time, cmf, ctime, fmf, ftime,
     110         3215 :                                         0, icomp, destination_mf.nComp(), m_geom[lev-1], m_geom[lev],
     111              :                                         physbc, 0,
     112              :                                         physbc, 0,
     113         3215 :                                         m_refRatio[lev-1],
     114              :                                         &node_bilinear, bcs, 0);
     115              : 
     116              :             }
     117              :             else
     118              :             {
     119            0 :                 Util::Abort(INFO,"This implementation is not yet complete.");
     120              :                 /*
     121              :                 Numeric::Interpolator::CellBilinear<T> *mapper 
     122              :                     = new Numeric::Interpolator::CellBilinear<T>();
     123              :                 m_bc->define(m_geom[lev]);
     124              :                 amrex::FillPatchTwoLevels(destination_mf, time, cmf, ctime, fmf, ftime,
     125              :                                         0, icomp, destination_mf.nComp(), m_geom[lev-1], m_geom[lev],
     126              :                                         *m_bc, 0,
     127              :                                         *m_bc, 0,
     128              :                                         m_refRatio[lev-1],
     129              :                                         mapper, bcs, 0);
     130              :                 */
     131              :             }
     132         3214 :         }
     133              : 
     134        42050 :     }
     135              :     void 
     136        41533 :     FillPatch (int lev, amrex::Real time) override
     137              :     {
     138        41533 :         this->FillPatch(lev,time,m_field,*(m_field[lev]),0);
     139        41532 :     }
     140              :     void
     141           42 :     FillCoarsePatch (int lev,
     142              :                     amrex::Real time,
     143              :                     int icomp,
     144              :                     int ncomp)
     145              :     {
     146              :         BL_PROFILE("Integrator::FillCoarsePatch");
     147              :         AMREX_ASSERT(lev > 0);
     148              : 
     149           42 :         if (m_gridtype == Set::Hypercube::Node)
     150              :         {
     151          336 :             Util::Assert(INFO, TEST(m_field[lev]->boxArray().ixType() == amrex::IndexType::TheNodeType()));
     152           42 :             EmptyBC physbc;
     153           42 :             amrex::Vector<amrex::FabArray<amrex::BaseFab<T>> *> cmf;
     154           42 :             cmf.push_back(m_field[lev-1].get());
     155           42 :             amrex::Vector<amrex::Real> ctime;
     156           42 :             ctime.push_back(time);
     157           42 :             amrex::Vector<amrex::BCRec> bcs(ncomp, physbc.GetBCRec());
     158           42 :             amrex::InterpFromCoarseLevel(*m_field[lev], time, *cmf[0], 0, icomp, ncomp, 
     159           42 :                                         m_geom[lev-1], m_geom[lev],
     160              :                                         physbc, 0,
     161              :                                         physbc, 0,
     162           42 :                                         m_refRatio[lev-1],
     163              :                                         &node_bilinear, bcs, 0);
     164           42 :         }
     165            0 :         else if (m_gridtype == Set::Hypercube::Cell)
     166              :         {
     167            0 :             Util::Abort(INFO,"This implementation is not yet complete");
     168              :             /*
     169              :             amrex::Vector<amrex::FabArray<amrex::BaseFab<T>> *> cmf;
     170              :             cmf.push_back(m_field[lev-1].get());
     171              :             amrex::Vector<amrex::Real> ctime;
     172              :             ctime.push_back(time);
     173              :             m_bc->define(m_geom[lev]);
     174              :             Numeric::Interpolator::CellBilinear<T> *mapper = new Numeric::Interpolator::CellBilinear<T>();
     175              :             amrex::Vector<amrex::BCRec> bcs(ncomp, m_bc->GetBCRec());
     176              :             amrex::InterpFromCoarseLevel(*m_field[lev], time, *cmf[0], 0, icomp, ncomp, 
     177              :                                         m_geom[lev-1], m_geom[lev],
     178              :                                         *m_bc, 0,
     179              :                                         *m_bc, 0,
     180              :                                         m_refRatio[lev-1],
     181              :                                         mapper, bcs, 0);
     182              :             */
     183              :         }
     184              :         else
     185            0 :             Util::Abort(INFO,"Invalid grid");
     186           42 :     }
     187              : 
     188              : 
     189          518 :     virtual void RemakeLevel (int lev,       
     190              :                             amrex::Real time, 
     191              :                             const amrex::BoxArray& cgrids, 
     192              :                             const amrex::DistributionMapping& dm) override
     193              :     {
     194          518 :         if (m_gridtype == Set::Hypercube::Node)
     195              :         {
     196         4144 :             Util::Assert(INFO, TEST(m_field[lev]->boxArray().ixType() == amrex::IndexType::TheNodeType()));
     197          518 :             amrex::BoxArray ngrids = cgrids;
     198          518 :             ngrids.convert(amrex::IntVect::TheNodeVector());
     199          518 :             amrex::FabArray<amrex::BaseFab<T>> new_state(ngrids, dm, m_ncomp, m_nghost);
     200          518 :             this->FillPatch(lev, time, m_field, new_state, 0);
     201          518 :             std::swap(new_state, *m_field[lev]);
     202          518 :         }
     203            0 :         else if (m_gridtype == Set::Hypercube::Cell)
     204              :         {
     205            0 :             amrex::FabArray<amrex::BaseFab<T>> new_state(cgrids, dm, m_ncomp, m_nghost);
     206            0 :             this->FillPatch(lev, time, m_field, new_state, 0);
     207            0 :             std::swap(new_state, *m_field[lev]);
     208            0 :         }
     209              :         else
     210            0 :             Util::Abort(INFO,"Invalid grid");
     211          518 :     }
     212              : 
     213           42 :     virtual void MakeNewLevelFromCoarse (int lev, 
     214              :                                         amrex::Real time, 
     215              :                                         const amrex::BoxArray& cgrids, 
     216              :                                         const amrex::DistributionMapping& dm) override
     217              :     {
     218           42 :         if (m_gridtype == Set::Hypercube::Node)
     219              :         {
     220           42 :             amrex::BoxArray ngrids = cgrids;
     221           42 :             ngrids.convert(amrex::IntVect::TheNodeVector());
     222           42 :             m_field[lev].reset(new amrex::FabArray<amrex::BaseFab<T>>(ngrids,dm,m_ncomp,m_nghost));
     223           42 :             FillCoarsePatch(lev,time,0,m_ncomp);
     224           42 :         }
     225            0 :         else if (m_gridtype == Set::Hypercube::Cell)
     226              :         {
     227            0 :             m_field[lev].reset(new amrex::FabArray<amrex::BaseFab<T>>(cgrids,dm,m_ncomp,m_nghost));
     228            0 :             FillCoarsePatch(lev,time,0,m_ncomp);
     229              :         }
     230              :         else
     231            0 :             Util::Abort(INFO,"Invalid grid");
     232           42 :     }
     233              : 
     234         1417 :     virtual void MakeNewLevelFromScratch (int lev, 
     235              :                                         amrex::Real /*time*/, 
     236              :                                         const amrex::BoxArray& cgrids,
     237              :                                         const amrex::DistributionMapping& dm) override
     238              :     {
     239         1417 :         if (m_gridtype == Set::Hypercube::Node)
     240              :         {
     241         1417 :             amrex::BoxArray ngrids = cgrids;
     242         1417 :             ngrids.convert(amrex::IntVect::TheNodeVector());
     243         1417 :             m_field[lev].reset(new amrex::FabArray<amrex::BaseFab<T>>(ngrids,dm,m_ncomp,m_nghost));
     244         1417 :             m_field[lev]->setVal(T::Zero());
     245         1417 :         }
     246            0 :         else if (m_gridtype == Set::Hypercube::Cell)
     247              :         {
     248            0 :             m_field[lev].reset(new amrex::FabArray<amrex::BaseFab<T>>(cgrids,dm,m_ncomp,m_nghost));
     249            0 :             m_field[lev]->setVal(T::Zero());
     250              :         }
     251              :         else
     252            0 :             Util::Abort(INFO,"Invalid grid");
     253         1417 :     }                                 
     254              : 
     255       125581 :     virtual void SetFinestLevel(const int a_finestlevel) override
     256              :     {
     257       125581 :         m_field.finest_level = a_finestlevel;
     258       125581 :     }
     259              : 
     260         1417 :     virtual void FillBoundary(const int lev, Set::Scalar time) override
     261              :     {
     262         1417 :         Util::RealFillBoundary(*m_field[lev],m_geom[lev]);
     263         1417 :         if (m_gridtype == Set::Hypercube::Cell)
     264              :         {
     265            0 :             m_bc->define(m_geom[lev]);
     266            0 :             for (amrex::MFIter mfi(*m_field[lev],true); mfi.isValid(); ++mfi)
     267              :             {
     268            0 :                 const amrex::Box& box = mfi.tilebox();
     269            0 :                 amrex::BaseFab<T>  &patch = (*(m_field[lev]))[mfi];
     270            0 :                 m_bc->FillBoundary(patch,box,m_nghost,0,m_ncomp,time);
     271              :             }
     272              :             //
     273              :         }
     274         1417 :     }
     275              :     
     276         1336 :     virtual void AverageDown(const int lev, amrex::IntVect refRatio) override
     277              :     {
     278         1336 :         if (m_gridtype == Set::Hypercube::Node)
     279         1336 :             amrex::average_down_nodal(*m_field[lev+1],*m_field[lev],refRatio);
     280            0 :         else if (m_gridtype == Set::Hypercube::Cell)
     281            0 :             Util::Abort(INFO,"This is not yet working");
     282              :             //amrex::average_down(*m_field[lev+1],*m_field[lev],0,m_ncomp,refRatio);
     283              :             //amrex::average_down(*m_field[lev+1],*m_field[lev],0,m_ncomp,refRatio);
     284              :         else
     285            0 :             Util::Abort(INFO,"Incorrect grid");
     286         1336 :     }
     287              :     
     288              : private:
     289              : 
     290              :     Set::Field<T> &m_field;
     291              :     const amrex::Vector<amrex::Geometry>  &m_geom;
     292              :     const amrex::Vector<amrex::IntVect> &m_refRatio;
     293              :     const int m_ncomp, m_nghost;
     294              :     BC::BC<T> *m_bc;
     295              :     
     296              :     Numeric::Interpolator::NodeBilinear<T> node_bilinear;
     297              : 
     298              : public:
     299        10055 :     virtual int NComp() override {
     300        10055 :         return m_field.NComp();
     301              :     }    
     302         3933 :     virtual void Copy(int a_lev, amrex::MultiFab &a_dst, int a_dstcomp, int a_nghost) override
     303              :     {
     304         3933 :         m_field.Copy(a_lev,a_dst,a_dstcomp,a_nghost);
     305         3933 :     }
     306          272 :     virtual void setName(std::string a_name) override {
     307          272 :         m_field.name = a_name;
     308          272 :     }
     309         3822 :     virtual std::string Name(int i) override {
     310         3822 :         return m_field.Name(i);
     311              :     }
     312            0 :     virtual void setBC(void * a_bc) override {
     313            0 :         m_bc = (BC::BC<T> *)(a_bc);
     314            0 :     }
     315            0 :     virtual void * getBC() override {
     316            0 :         return (void*)m_bc;
     317              :     }
     318              : 
     319              : };
     320              : 
     321              : }
     322              : 
     323              : #endif
        

Generated by: LCOV version 2.0-1