LCOV - code coverage report
Current view: top level - src/Integrator - BaseField.H (source / functions) Hit Total Coverage
Test: coverage_merged.info Lines: 77 126 61.1 %
Date: 2024-11-18 05:28:54 Functions: 103 468 22.0 %

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