LCOV - code coverage report
Current view: top level - src/BC - Constant.H (source / functions) Coverage Total Hit
Test: coverage_merged.info Lines: 83.3 % 108 90
Test Date: 2025-02-27 04:17:48 Functions: 100.0 % 5 5

            Line data    Source code
       1              : //
       2              : // This is the most commonly used standard boundary condition implementation.
       3              : // The name "Constant" refers to the invariance of the BC value or character along each face
       4              : // of the simulation domain; however, you may cause a change in the value with time by using a
       5              : // :ref:`Numeric::Interpolator::Linear` string.
       6              : // 
       7              : // The BC on each face is specified with a :code:`type` string that specifies the nature of 
       8              : // the BC, and a :code:`val` that specifies the value.
       9              : // By default, all types are Dirichlet and all values are 0.0.
      10              : // The complete list of BC types are below:
      11              : //
      12              : // `Dirichlet <https://en.wikipedia.org/wiki/Dirichlet_boundary_condition>`_  boundary condition
      13              : // types can be specified with :code:`Dirichlet`, :code:`dirichlet`, :code:`EXT_DIR`.
      14              : // `Neumann <https://en.wikipedia.org/wiki/Neumann_boundary_condition>`_ boundary condition
      15              : // types are specified with :code:`Neumann`, :code:`neumann`.
      16              : // `Periodic <https://en.wikipedia.org/wiki/Periodic_boundary_conditions>`_ boundary conditions
      17              : // can be specified with :code:`Periodic`, :code:`periodic`, :code:`INT_DIR`.
      18              : // **Important**: Ensure that your geometry is specified to be periodic using :code:`geometry.is_periodic`.
      19              : // For instance, if periodic in x, set to :code:`1 0 0`
      20              : //
      21              : // The BC values can be specified either as a number (e.g. :code:`1.0`) or using a linear interpolator
      22              : // string (e.g. :code:`(0,1:2.3,-0.1)`).
      23              : //
      24              : // The number of values and types must be either 0 (for defaults), 1 (to set the same for all field components)
      25              : // or N (where N=number of field components).
      26              : //
      27              : 
      28              : #ifndef BC_CONSTANT_H_
      29              : #define BC_CONSTANT_H_
      30              : 
      31              : #include <AMReX_ParallelDescriptor.H>
      32              : #include <AMReX_ParmParse.H>
      33              : #include <AMReX_BCRec.H>
      34              : #include <AMReX_PhysBCFunct.H>
      35              : #include <AMReX_Array.H>
      36              : 
      37              : #include "Set/Set.H"
      38              : #include "BC/BC.H"
      39              : #include "Numeric/Interpolator/Linear.H"
      40              : 
      41              : namespace BC
      42              : {
      43              : class Constant
      44              :     : public BC<Set::Scalar>
      45              : {
      46              : 
      47              : #if AMREX_SPACEDIM==2
      48              :     enum Face {
      49              :         XLO, YLO, XHI, YHI,
      50              :         INT
      51              :     };
      52              : #elif AMREX_SPACEDIM==3
      53              :     enum Face {
      54              :         XLO, YLO, ZLO, XHI, YHI, ZHI, // 6
      55              :         INT
      56              :     };
      57              : #endif
      58              : 
      59              : public:
      60              :     static constexpr const char* name = "constant";
      61              : 
      62              :     //Constant (amrex::Vector<amrex::Geometry> &_geom) : geom(_geom) {};
      63            7 :     Constant(int a_ncomp) : m_ncomp(a_ncomp) {};
      64           25 :     Constant(int a_ncomp, IO::ParmParse& pp, std::string name) : m_ncomp(a_ncomp)
      65              :     {
      66           75 :         pp_queryclass(name, *this);
      67           25 :     };
      68              :     Constant(int ncomp, amrex::Vector<std::string> bc_hi_str,
      69              :         amrex::Vector<std::string> bc_lo_str,
      70              :         AMREX_D_DECL(amrex::Vector<amrex::Real> _bc_lo_1,
      71              :             amrex::Vector<amrex::Real> _bc_lo_2,
      72              :             amrex::Vector<amrex::Real> _bc_lo_3),
      73              :         AMREX_D_DECL(amrex::Vector<amrex::Real> _bc_hi_1,
      74              :             amrex::Vector<amrex::Real> _bc_hi_2,
      75              :             amrex::Vector<amrex::Real> _bc_hi_3));
      76              : 
      77              :     static Constant ZeroNeumann(int ncomp = 1)
      78              :     {
      79              :         Constant ret = Constant(ncomp);
      80              : 
      81              :         for (int d = 0; d < m_nfaces; d++)
      82              :         {
      83              :             ret.m_bc_type[d].clear();
      84              :             for (int n = 0; n < ncomp; n++)
      85              :             {
      86              :                 ret.m_bc_type[d].push_back((int)amrex::LinOpBCType::Neumann);
      87              :                 ret.m_bc_val[d].push_back (0.0);;
      88              :             }
      89              :         }
      90              : 
      91              :         return ret;
      92              :     }
      93              : 
      94              :     static Constant ZeroDirichlet(int ncomp = 1)
      95              :     {
      96              :         Constant ret = Constant(ncomp);
      97              : 
      98              :         for (int d = 0; d < m_nfaces; d++)
      99              :             for (int n = 0; n < ncomp; n++)
     100              :             {
     101              :                 ret.m_bc_type[n][d] = (int)amrex::LinOpBCType::Dirichlet;
     102              :                 ret.m_bc_val [n][d]  = 0.0;
     103              :             }
     104              : 
     105              :         return ret;
     106              :     }
     107              : 
     108              : 
     109           30 :     virtual ~Constant() {};
     110              : 
     111              :     virtual void FillBoundary(amrex::BaseFab<Set::Scalar>& in, const amrex::Box& box,
     112              :         int ngrow, int dcomp, int ncomp, amrex::Real time,
     113              :         Orientation face = Orientation::All,
     114              :         const amrex::Mask* mask = nullptr) override;
     115              : 
     116              :     using BC::FillBoundary;
     117              : 
     118              :     amrex::BCRec GetBCRec() override;
     119              :     virtual amrex::Array<int, AMREX_SPACEDIM> IsPeriodic() override;
     120              :     virtual amrex::Periodicity Periodicity() const override;
     121              :     virtual amrex::Periodicity Periodicity(const amrex::Box& b) override;
     122              : 
     123              : 
     124              : 
     125              :     template<class T>
     126              :     const amrex::Array<amrex::Array<T, AMREX_SPACEDIM>, 2> GetBCTypes()
     127              :     {
     128              :         return { {{AMREX_D_DECL((T)m_bc_type[Face::XLO][0],(T)m_bc_type[Face::YLO][0],(T)m_bc_type[Face::ZLO][0])},
     129              :                 {AMREX_D_DECL((T)m_bc_type[Face::XLO][0],(T)m_bc_type[Face::YLO][0],(T)m_bc_type[Face::ZLO][0])}} };
     130              :     }
     131              : 
     132              : 
     133              : private:
     134              : #if AMREX_SPACEDIM==2
     135              :     static const int m_nfaces = 4;
     136              : #elif AMREX_SPACEDIM==3
     137              :     static const int m_nfaces = 6;
     138              : #endif
     139              : 
     140              :     unsigned int m_ncomp = 0;
     141              : 
     142              :     //int bc_lo[BL_SPACEDIM];
     143              :     //int bc_hi[BL_SPACEDIM];
     144              :     //amrex::Vector<amrex::Real> AMREX_D_DECL(bc_lo_1, bc_lo_2, bc_lo_3);
     145              :     //amrex::Vector<amrex::Real> AMREX_D_DECL(bc_hi_1, bc_hi_2, bc_hi_3);
     146              : 
     147              :     std::array<std::vector<int>, m_nfaces> m_bc_type;
     148              :     std::array<std::vector<Numeric::Interpolator::Linear<Set::Scalar>>, m_nfaces> m_bc_val;
     149              : 
     150              : public:
     151           32 :     static void Parse(Constant& value, IO::ParmParse& pp)
     152              :     {
     153           32 :         std::map<std::string, int> bcmap;
     154           64 :         bcmap["BOGUS_BC"] = amrex::BCType::mathematicalBndryTypes::bogus;
     155           64 :         bcmap["INT_DIR"] = amrex::BCType::mathematicalBndryTypes::int_dir;
     156           64 :         bcmap["REFLECT_ODD"] = amrex::BCType::mathematicalBndryTypes::reflect_odd;
     157           64 :         bcmap["INT_DIR"] = amrex::BCType::mathematicalBndryTypes::int_dir;
     158           64 :         bcmap["REFLECT_EVEN"] = amrex::BCType::mathematicalBndryTypes::reflect_even;
     159           64 :         bcmap["FOEXTRAP"] = amrex::BCType::mathematicalBndryTypes::foextrap;
     160           64 :         bcmap["EXT_DIR"] = amrex::BCType::mathematicalBndryTypes::ext_dir;
     161           64 :         bcmap["HOEXTRAP"] = amrex::BCType::mathematicalBndryTypes::hoextrap;
     162           64 :         bcmap["Interior"] = amrex::BCType::mathematicalBndryTypes::int_dir;
     163           64 :         bcmap["Inflow"] = amrex::BCType::mathematicalBndryTypes::ext_dir;
     164           64 :         bcmap["Outflow"] = amrex::BCType::mathematicalBndryTypes::foextrap;
     165           64 :         bcmap["Symmetry"] = amrex::BCType::mathematicalBndryTypes::reflect_even;
     166           64 :         bcmap["SlipWall"] = amrex::BCType::mathematicalBndryTypes::ext_dir;
     167           64 :         bcmap["NoSlipWall"] = amrex::BCType::mathematicalBndryTypes::ext_dir;
     168              :         // From <AMReX_LO_BCTYPES.H>
     169           64 :         bcmap["interior"] = (int)amrex::LinOpBCType::interior;
     170           64 :         bcmap["Dirichlet"] = (int)amrex::LinOpBCType::Dirichlet;
     171           64 :         bcmap["dirichlet"] = (int)amrex::LinOpBCType::Dirichlet;
     172           64 :         bcmap["Neumann"] = (int)amrex::LinOpBCType::Neumann;
     173           64 :         bcmap["NEUMANN"] = (int)amrex::LinOpBCType::Neumann;
     174           64 :         bcmap["neumann"] = (int)amrex::LinOpBCType::Neumann;
     175           64 :         bcmap["reflect_odd"] = (int)amrex::LinOpBCType::reflect_odd;
     176           64 :         bcmap["Marshak"] = (int)amrex::LinOpBCType::Marshak;
     177           64 :         bcmap["SanchezPomraning"] = (int)amrex::LinOpBCType::SanchezPomraning;
     178           64 :         bcmap["inflow"] = (int)amrex::LinOpBCType::inflow;
     179           64 :         bcmap["Periodic"] = (int)amrex::LinOpBCType::Periodic;
     180           32 :         bcmap["periodic"] = (int)amrex::LinOpBCType::Periodic;
     181              : 
     182              : 
     183              : 
     184           32 :         value.m_bc_type[Face::XLO].clear(); value.m_bc_val[Face::XLO].clear();
     185           32 :         value.m_bc_type[Face::XHI].clear(); value.m_bc_val[Face::XHI].clear();
     186           32 :         value.m_bc_type[Face::YLO].clear(); value.m_bc_val[Face::YLO].clear();
     187           32 :         value.m_bc_type[Face::YHI].clear(); value.m_bc_val[Face::YHI].clear();
     188              : #if AMREX_SPACEDIM == 3
     189            1 :         value.m_bc_type[Face::ZLO].clear(); value.m_bc_val[Face::ZLO].clear();
     190            1 :         value.m_bc_type[Face::ZHI].clear(); value.m_bc_val[Face::ZHI].clear();
     191              : #endif
     192              : 
     193              :         // TYPES
     194              : 
     195           32 :         std::vector<std::string> str;
     196          160 :         pp_queryarr("type.xlo", str);  // BC type on the lower x edge (2d) face (3d)
     197           64 :         for (unsigned int i = 0; i < str.size(); i++) if (!bcmap.count(str[i])) Util::Exception(INFO, "Invalid BC: ", str[i]);
     198           55 :         if (str.size() == value.m_ncomp) for (unsigned int i = 0; i < value.m_ncomp; i++) value.m_bc_type[Face::XLO].push_back(bcmap[str[i]]);
     199            9 :         else if (str.size() == 1) value.m_bc_type[Face::XLO].resize(value.m_ncomp, bcmap[str[0]]);
     200            0 :         else Util::Exception(INFO, "Incorrect number of ", pp.prefix(), " BC type args: expected ", value.m_ncomp, " or 1 but got ", str.size());
     201          160 :         pp_queryarr("type.xhi", str);  // BC type on the upper x edge (2d) face (3d)
     202           64 :         for (unsigned int i = 0; i < str.size(); i++) if (!bcmap.count(str[i])) Util::Exception(INFO, "Invalid BC: ", str[i]);
     203           55 :         if (str.size() == value.m_ncomp) for (unsigned int i = 0; i < value.m_ncomp; i++) value.m_bc_type[Face::XHI].push_back(bcmap[str[i]]);
     204            9 :         else if (str.size() == 1) value.m_bc_type[Face::XHI].resize(value.m_ncomp, bcmap[str[0]]);
     205            0 :         else Util::Exception(INFO, "Incorrect number of ", pp.prefix(), " BC type args: expected ", value.m_ncomp, " or 1 but got ", str.size());
     206          160 :         pp_queryarr("type.ylo", str);  // BC type on the lower y edge (2d) face (3d)
     207           64 :         for (unsigned int i = 0; i < str.size(); i++) if (!bcmap.count(str[i])) Util::Exception(INFO, "Invalid BC: ", str[i]);
     208           55 :         if (str.size() == value.m_ncomp) for (unsigned int i = 0; i < value.m_ncomp; i++) value.m_bc_type[Face::YLO].push_back(bcmap[str[i]]);
     209            9 :         else if (str.size() == 1) value.m_bc_type[Face::YLO].resize(value.m_ncomp, bcmap[str[0]]);
     210            0 :         else Util::Exception(INFO, "Incorrect number of ", pp.prefix(), " BC type args: expected ", value.m_ncomp, " or 1 but got ", str.size());
     211          160 :         pp_queryarr("type.yhi", str);  // BC type on the upper y edge (2d) face (3d)
     212           64 :         for (unsigned int i = 0; i < str.size(); i++) if (!bcmap.count(str[i])) Util::Exception(INFO, "Invalid BC: ", str[i]);
     213           55 :         if (str.size() == value.m_ncomp) for (unsigned int i = 0; i < value.m_ncomp; i++) value.m_bc_type[Face::YHI].push_back(bcmap[str[i]]);
     214            9 :         else if (str.size() == 1) value.m_bc_type[Face::YHI].resize(value.m_ncomp, bcmap[str[0]]);
     215            0 :         else Util::Exception(INFO, "Incorrect number of ", pp.prefix(), " BC type args: expected ", value.m_ncomp, " or 1 but got ", str.size());
     216          191 :         pp_queryarr("type.zlo", str);  // BC type on the lower z face (processed but ignored in 2d to prevent unused input errors)
     217              : #if AMREX_SPACEDIM==3
     218            2 :         for (unsigned int i = 0; i < str.size(); i++) if (!bcmap.count(str[i])) Util::Exception(INFO, "Invalid BC: ", str[i]);
     219            2 :         if (str.size() == value.m_ncomp) for (unsigned int i = 0; i < value.m_ncomp; i++) value.m_bc_type[Face::ZLO].push_back(bcmap[str[i]]);
     220            0 :         else if (str.size() == 1) value.m_bc_type[Face::ZLO].resize(value.m_ncomp, bcmap[str[0]]);
     221            0 :         else Util::Exception(INFO, "Incorrect number of ", pp.prefix(), " BC type args: expected ", value.m_ncomp, " or 1 but got ", str.size());
     222              : #endif
     223          160 :         pp_queryarr("type.zhi", str);  // BC type on the upper z face (processed but ignored in 2d to prevent unused input errors)
     224              : #if AMREX_SPACEDIM==3
     225            2 :         for (unsigned int i = 0; i < str.size(); i++) if (!bcmap.count(str[i])) Util::Exception(INFO, "Invalid BC: ", str[i]);
     226            2 :         if (str.size() == value.m_ncomp) for (unsigned int i = 0; i < value.m_ncomp; i++) value.m_bc_type[Face::ZHI].push_back(bcmap[str[i]]);
     227            0 :         else if (str.size() == 1) value.m_bc_type[Face::ZHI].resize(value.m_ncomp, bcmap[str[0]]);
     228            0 :         else Util::Exception(INFO, "Incorrect number of ", pp.prefix(), " BC type args: expected ", value.m_ncomp, " or 1 but got ", str.size());
     229              : #endif
     230              : 
     231              :         // VALS
     232           32 :         std::vector<std::string> val;
     233           32 :         value.m_bc_val[Face::XLO].clear();
     234          160 :         pp_queryarr("val.xlo", val);  // BC value on the lower x edge (2d) face (3d)
     235           49 :         if (val.size() == value.m_ncomp) for (unsigned int i = 0; i < value.m_ncomp; i++) value.m_bc_val[Face::XLO].push_back(Numeric::Interpolator::Linear<Set::Scalar>(val[i]));
     236           15 :         else if (val.size() == 1) value.m_bc_val[Face::XLO].resize(value.m_ncomp, Numeric::Interpolator::Linear<Set::Scalar>(val[0]));
     237           15 :         else if (val.size() == 0) value.m_bc_val[Face::XLO].resize(value.m_ncomp, 0.0);
     238            0 :         else Util::Exception(INFO, "Incorrect number of ", pp.prefix(), " BC value args: expected ", value.m_ncomp, " or 0 or 1 but got ", val.size());
     239           32 :         value.m_bc_val[Face::XHI].clear();
     240          160 :         pp_queryarr("val.xhi", val); // BC value on the upper x edge (2d) face (3d)
     241           49 :         if (val.size() == value.m_ncomp) for (unsigned int i = 0; i < value.m_ncomp; i++) value.m_bc_val[Face::XHI].push_back(Numeric::Interpolator::Linear<Set::Scalar>(val[i]));
     242           15 :         else if (val.size() == 1) value.m_bc_val[Face::XHI].resize(value.m_ncomp, Numeric::Interpolator::Linear<Set::Scalar>(val[0]));
     243           15 :         else if (val.size() == 0) value.m_bc_val[Face::XHI].resize(value.m_ncomp, 0.0);
     244            0 :         else Util::Exception(INFO, "Incorrect number of ", pp.prefix(), " BC value args: expected ", value.m_ncomp, " or 0 or 1 but got ", val.size());
     245           32 :         value.m_bc_val[Face::YLO].clear();
     246          160 :         pp_queryarr("val.ylo", val);  // BC value on the lower y edge (2d) face (3d)
     247           53 :         if (val.size() == value.m_ncomp) for (unsigned int i = 0; i < value.m_ncomp; i++) value.m_bc_val[Face::YLO].push_back(Numeric::Interpolator::Linear<Set::Scalar>(val[i]));
     248           13 :         else if (val.size() == 1) value.m_bc_val[Face::YLO].resize(value.m_ncomp, Numeric::Interpolator::Linear<Set::Scalar>(val[0]));
     249           13 :         else if (val.size() == 0) value.m_bc_val[Face::YLO].resize(value.m_ncomp, 0.0);
     250            0 :         else Util::Exception(INFO, "Incorrect number of ", pp.prefix(), " BC value args: expected ", value.m_ncomp, " or 0 or 1 but got ", val.size());
     251           32 :         value.m_bc_val[Face::YHI].clear();
     252          160 :         pp_queryarr("val.yhi", val); // BC value on the upper y edge (2d) face (3d)
     253           53 :         if (val.size() == value.m_ncomp) for (unsigned int i = 0; i < value.m_ncomp; i++) value.m_bc_val[Face::YHI].push_back(Numeric::Interpolator::Linear<Set::Scalar>(val[i]));
     254           13 :         else if (val.size() == 1) value.m_bc_val[Face::YHI].resize(value.m_ncomp, Numeric::Interpolator::Linear<Set::Scalar>(val[0]));
     255           13 :         else if (val.size() == 0) value.m_bc_val[Face::YHI].resize(value.m_ncomp, 0.0);
     256            0 :         else Util::Exception(INFO, "Incorrect number of ", pp.prefix(), " BC value args: expected ", value.m_ncomp, " or 0 or 1 but got ", val.size());
     257          191 :         pp_queryarr("val.zlo", val);  // BC value on the lower z face (processed but ignored in 2d to prevent unused input errors)
     258              : #if AMREX_SPACEDIM==3
     259            1 :         value.m_bc_val[Face::ZLO].clear();
     260            2 :         if (val.size() == value.m_ncomp) for (unsigned int i = 0; i < value.m_ncomp; i++) value.m_bc_val[Face::ZLO].push_back(Numeric::Interpolator::Linear<Set::Scalar>(val[i]));
     261            0 :         else if (val.size() == 1) value.m_bc_val[Face::ZLO].resize(value.m_ncomp, Numeric::Interpolator::Linear<Set::Scalar>(val[0]));
     262            0 :         else if (val.size() == 0) value.m_bc_val[Face::ZLO].resize(value.m_ncomp, 0.0);
     263            0 :         else Util::Exception(INFO, "Incorrect number of ", pp.prefix(), " BC value args: expected ", value.m_ncomp, " or 0 or 1 but got ", val.size());
     264              : #endif
     265          160 :         pp_queryarr("val.zhi", val); // BC value on the upper z face (processed but ignored in 2d to prevent unused input errors)
     266              : #if AMREX_SPACEDIM==3
     267            1 :         value.m_bc_val[Face::ZHI].clear();
     268            2 :         if (val.size() == value.m_ncomp) for (unsigned int i = 0; i < value.m_ncomp; i++) value.m_bc_val[Face::ZHI].push_back(Numeric::Interpolator::Linear<Set::Scalar>(val[i]));
     269            0 :         else if (val.size() == 1) value.m_bc_val[Face::ZHI].resize(value.m_ncomp, Numeric::Interpolator::Linear<Set::Scalar>(val[0]));
     270            0 :         else if (val.size() == 0) value.m_bc_val[Face::ZHI].resize(value.m_ncomp, 0.0);
     271            0 :         else Util::Exception(INFO, "Incorrect number of ", pp.prefix(), " BC value args: expected ", value.m_ncomp, " or 0 or 1 but got ", val.size());
     272              : #endif
     273           32 :     }
     274              : 
     275              : };
     276              : }
     277              : #endif
        

Generated by: LCOV version 2.0-1