LCOV - code coverage report
Current view: top level - src/BC - Expression.H (source / functions) Coverage Total Hit
Test: coverage_merged.info Lines: 0.0 % 79 0
Test Date: 2025-08-12 17:45:17 Functions: 0.0 % 5 0

            Line data    Source code
       1              : //
       2              : // Boundary condition similar to BC::Constant, except that "values"
       3              : // are given as strings which are functions of x,y,z,t.
       4              : //
       5              : 
       6              : #ifndef BC_EXPRESSION_H_
       7              : #define BC_EXPRESSION_H_
       8              : 
       9              : #include <AMReX_ParallelDescriptor.H>
      10              : #include <AMReX_ParmParse.H>
      11              : #include <AMReX_BCRec.H>
      12              : #include <AMReX_PhysBCFunct.H>
      13              : #include <AMReX_Array.H>
      14              : #include <AMReX_Parser.H>
      15              : 
      16              : #include "IO/ParmParse.H"
      17              : #include "BC/BC.H"
      18              : 
      19              : namespace BC
      20              : {
      21              : class Expression
      22              :     : public BC<Set::Scalar>
      23              : {
      24              : public:
      25              :     static constexpr const char* name = "expression";
      26              : 
      27              :     //static constexpr const char* const Elastic::strings[];
      28              :     #if AMREX_SPACEDIM==2
      29              :     static const constexpr char * const facestr[] = {
      30              :         "xlo","ylo","xhi","yhi"
      31              :     };
      32              :     #elif AMREX_SPACEDIM==3
      33              :     static const constexpr char * const facestr[] = {
      34              :         "xlo","ylo","zlo","xhi","yhi","zhi",
      35              :     };
      36              :     #endif
      37              : 
      38              : #if AMREX_SPACEDIM==2
      39              :     enum Face {
      40              :         XLO, YLO, XHI, YHI,
      41              :         INT
      42              :     };
      43              : #elif AMREX_SPACEDIM==3
      44              :     enum Face {
      45              :         XLO, YLO, ZLO, XHI, YHI, ZHI, // 6
      46              :         INT
      47              :     };
      48              : #endif
      49              : 
      50              : public:
      51              :     //Constant (amrex::Vector<amrex::Geometry> &_geom) : geom(_geom) {};
      52              :     Expression(int a_ncomp) : m_ncomp(a_ncomp) {};
      53            0 :     Expression(int a_ncomp, IO::ParmParse& pp, std::string name) : m_ncomp(a_ncomp)
      54              :     {
      55            0 :         pp_queryclass(name, *this);
      56            0 :     };
      57            0 :     Expression(int a_ncomp, Unit /*a_unit*/, IO::ParmParse& pp, std::string name) : m_ncomp(a_ncomp)
      58              :     {
      59            0 :         pp_queryclass(name, *this);
      60            0 :     };
      61              : 
      62            0 :     virtual ~Expression() {};
      63              : 
      64              :     virtual void FillBoundary(amrex::BaseFab<Set::Scalar>& in, const amrex::Box& box,
      65              :         int ngrow, int dcomp, int ncomp, amrex::Real time,
      66              :         Orientation face = Orientation::All,
      67              :         const amrex::Mask* mask = nullptr) override;
      68              : 
      69              :     using BC::FillBoundary;
      70              : 
      71              :     amrex::BCRec GetBCRec() override;
      72              :     virtual amrex::Array<int, AMREX_SPACEDIM> IsPeriodic() override;
      73              :     virtual amrex::Periodicity Periodicity() const override;
      74              :     virtual amrex::Periodicity Periodicity(const amrex::Box& b) override;
      75              : 
      76              : 
      77              : 
      78              :     template<class T>
      79              :     const amrex::Array<amrex::Array<T, AMREX_SPACEDIM>, 2> GetBCTypes()
      80              :     {
      81              :         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])},
      82              :                 {AMREX_D_DECL((T)m_bc_type[Face::XLO][0],(T)m_bc_type[Face::YLO][0],(T)m_bc_type[Face::ZLO][0])}} };
      83              :     }
      84              : 
      85              : 
      86              : private:
      87              : #if AMREX_SPACEDIM==2
      88              :     static const int m_nfaces = 4;
      89              : #elif AMREX_SPACEDIM==3
      90              :     static const int m_nfaces = 6;
      91              : #endif
      92              : 
      93              :     unsigned int m_ncomp = 0;
      94              : 
      95              :     std::array<std::vector<int>, m_nfaces> m_bc_type;
      96              :     std::array<std::vector<amrex::Parser>, m_nfaces> m_bc_func_parser; 
      97              :     std::array<std::vector<amrex::ParserExecutor<4>>, m_nfaces> m_bc_func; 
      98              : 
      99              :     //std::array<std::vector<Numeric::Interpolator::Linear<Set::Scalar>>, m_nfaces> m_bc_val;
     100              : 
     101              : public:
     102            0 :     static void Parse(Expression& value, IO::ParmParse& pp)
     103              :     {
     104            0 :         std::map<std::string, int> bcmap;
     105            0 :         bcmap["BOGUS_BC"] = amrex::BCType::mathematicalBndryTypes::bogus;
     106            0 :         bcmap["INT_DIR"] = amrex::BCType::mathematicalBndryTypes::int_dir;
     107            0 :         bcmap["REFLECT_ODD"] = amrex::BCType::mathematicalBndryTypes::reflect_odd;
     108            0 :         bcmap["INT_DIR"] = amrex::BCType::mathematicalBndryTypes::int_dir;
     109            0 :         bcmap["REFLECT_EVEN"] = amrex::BCType::mathematicalBndryTypes::reflect_even;
     110            0 :         bcmap["FOEXTRAP"] = amrex::BCType::mathematicalBndryTypes::foextrap;
     111            0 :         bcmap["EXT_DIR"] = amrex::BCType::mathematicalBndryTypes::ext_dir;
     112            0 :         bcmap["HOEXTRAP"] = amrex::BCType::mathematicalBndryTypes::hoextrap;
     113            0 :         bcmap["Interior"] = amrex::BCType::mathematicalBndryTypes::int_dir;
     114            0 :         bcmap["Inflow"] = amrex::BCType::mathematicalBndryTypes::ext_dir;
     115            0 :         bcmap["Outflow"] = amrex::BCType::mathematicalBndryTypes::foextrap;
     116            0 :         bcmap["Symmetry"] = amrex::BCType::mathematicalBndryTypes::reflect_even;
     117            0 :         bcmap["SlipWall"] = amrex::BCType::mathematicalBndryTypes::ext_dir;
     118            0 :         bcmap["NoSlipWall"] = amrex::BCType::mathematicalBndryTypes::ext_dir;
     119              :         // From <AMReX_LO_BCTYPES.H>
     120            0 :         bcmap["interior"] = (int)amrex::LinOpBCType::interior;
     121            0 :         bcmap["Dirichlet"] = (int)amrex::LinOpBCType::Dirichlet;
     122            0 :         bcmap["dirichlet"] = (int)amrex::LinOpBCType::Dirichlet;
     123            0 :         bcmap["Neumann"] = (int)amrex::LinOpBCType::Neumann;
     124            0 :         bcmap["NEUMANN"] = (int)amrex::LinOpBCType::Neumann;
     125            0 :         bcmap["neumann"] = (int)amrex::LinOpBCType::Neumann;
     126            0 :         bcmap["reflect_odd"] = (int)amrex::LinOpBCType::reflect_odd;
     127            0 :         bcmap["Marshak"] = (int)amrex::LinOpBCType::Marshak;
     128            0 :         bcmap["SanchezPomraning"] = (int)amrex::LinOpBCType::SanchezPomraning;
     129            0 :         bcmap["inflow"] = (int)amrex::LinOpBCType::inflow;
     130            0 :         bcmap["Periodic"] = (int)amrex::LinOpBCType::Periodic;
     131            0 :         bcmap["periodic"] = (int)amrex::LinOpBCType::Periodic;
     132              : 
     133              : 
     134              : 
     135              :         // TYPES
     136              : 
     137            0 :         std::vector<std::string> str;
     138            0 :         pp.queryarr_default("type.xlo", str,{"dirichlet"});  // BC type on the lower x edge (2d) face (3d)
     139            0 :         for (unsigned int i = 0; i < str.size(); i++) if (!bcmap.count(str[i])) Util::Abort(INFO, "Invalid BC: ", str[i]);
     140            0 :         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]]);
     141            0 :         else if (str.size() == 1) value.m_bc_type[Face::XLO].resize(value.m_ncomp, bcmap[str[0]]);
     142            0 :         else Util::Abort(INFO, "Incorrect number of ", pp.prefix(), " BC type args: expected ", value.m_ncomp, " or 1 but got ", str.size());
     143            0 :         pp.queryarr_default("type.xhi", str,{"dirichlet"});  // BC type on the upper x edge (2d) face (3d)
     144            0 :         for (unsigned int i = 0; i < str.size(); i++) if (!bcmap.count(str[i])) Util::Abort(INFO, "Invalid BC: ", str[i]);
     145            0 :         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]]);
     146            0 :         else if (str.size() == 1) value.m_bc_type[Face::XHI].resize(value.m_ncomp, bcmap[str[0]]);
     147            0 :         else Util::Abort(INFO, "Incorrect number of ", pp.prefix(), " BC type args: expected ", value.m_ncomp, " or 1 but got ", str.size());
     148            0 :         pp.queryarr_default("type.ylo", str,{"dirichlet"});  // BC type on the lower y edge (2d) face (3d)
     149            0 :         for (unsigned int i = 0; i < str.size(); i++) if (!bcmap.count(str[i])) Util::Abort(INFO, "Invalid BC: ", str[i]);
     150            0 :         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]]);
     151            0 :         else if (str.size() == 1) value.m_bc_type[Face::YLO].resize(value.m_ncomp, bcmap[str[0]]);
     152            0 :         else Util::Abort(INFO, "Incorrect number of ", pp.prefix(), " BC type args: expected ", value.m_ncomp, " or 1 but got ", str.size());
     153            0 :         pp.queryarr_default("type.yhi", str,{"dirichlet"});  // BC type on the upper y edge (2d) face (3d)
     154            0 :         for (unsigned int i = 0; i < str.size(); i++) if (!bcmap.count(str[i])) Util::Abort(INFO, "Invalid BC: ", str[i]);
     155            0 :         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]]);
     156            0 :         else if (str.size() == 1) value.m_bc_type[Face::YHI].resize(value.m_ncomp, bcmap[str[0]]);
     157            0 :         else Util::Abort(INFO, "Incorrect number of ", pp.prefix(), " BC type args: expected ", value.m_ncomp, " or 1 but got ", str.size());
     158            0 :         pp.queryarr_default("type.zlo", str,{"dirichlet"});  // BC type on the lower z face (processed but ignored in 2d to prevent unused input errors)
     159              : #if AMREX_SPACEDIM==3
     160              :         for (unsigned int i = 0; i < str.size(); i++) if (!bcmap.count(str[i])) Util::Abort(INFO, "Invalid BC: ", str[i]);
     161              :         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]]);
     162              :         else if (str.size() == 1) value.m_bc_type[Face::ZLO].resize(value.m_ncomp, bcmap[str[0]]);
     163              :         else Util::Abort(INFO, "Incorrect number of ", pp.prefix(), " BC type args: expected ", value.m_ncomp, " or 1 but got ", str.size());
     164              : #endif
     165            0 :         pp.queryarr_default("type.zhi", str,{"dirichlet"});  // BC type on the upper z face (processed but ignored in 2d to prevent unused input errors)
     166              : #if AMREX_SPACEDIM==3
     167              :         for (unsigned int i = 0; i < str.size(); i++) if (!bcmap.count(str[i])) Util::Abort(INFO, "Invalid BC: ", str[i]);
     168              :         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]]);
     169              :         else if (str.size() == 1) value.m_bc_type[Face::ZHI].resize(value.m_ncomp, bcmap[str[0]]);
     170              :         else Util::Abort(INFO, "Incorrect number of ", pp.prefix(), " BC type args: expected ", value.m_ncomp, " or 1 but got ", str.size());
     171              : #endif
     172              : 
     173              :         // VALS
     174            0 :         std::vector<std::string> val;
     175            0 :         for (int face = 0; face != Face::INT; face++)
     176              :         {
     177            0 :             std::string querystr = std::string("val.") + std::string(facestr[face]);
     178            0 :             if (pp.contains(querystr.c_str())) pp_queryarr(querystr.c_str(),val);
     179            0 :             else val.resize(value.m_ncomp,"0.0");
     180            0 :             if (val.size() != value.m_ncomp) Util::Abort(INFO,"Incorrect number of expressions specified for ",querystr,": expected 1 or ",value.m_ncomp," but received ",val.size());
     181              : 
     182            0 :             value.m_bc_func_parser[face].clear();
     183            0 :             value.m_bc_func[face].clear();
     184            0 :             for (unsigned int i = 0 ; i < value.m_ncomp; i++)
     185              :             {
     186            0 :                 value.m_bc_func_parser[face].push_back( amrex::Parser(val[i].c_str()) );
     187            0 :                 value.m_bc_func_parser[face][i].registerVariables({"x","y","z","t"});
     188            0 :                 value.m_bc_func[face].push_back( value.m_bc_func_parser[face][i].compile<4>() );
     189              :             }
     190            0 :         }
     191              : 
     192              : #if AMREX_SPACEDIM==2
     193              :         // We may wish to use an input file that has 3D BC inputs
     194              :         // This will prevent the parser from complaining that there are unused inputs.
     195              :         std::vector<std::string> ignore_in_2d = {
     196              :             "zlo","zhi",
     197              :             "zhixlo","zloxlo","zhixhi","zloxhi","ylozlo","ylozhi","yhizlo","yhizhi",
     198            0 :             "xloylozlo","xloylozhi","xloyhizlo","xloyhizhi","xhiylozlo","xhiylozhi","xhiyhizlo","xhiyhizhi"};
     199            0 :         for (unsigned int n = 0; n < ignore_in_2d.size(); n++)
     200              :         {
     201            0 :             std::string querystr = std::string("val.") + ignore_in_2d[n];
     202            0 :             pp.ignore(querystr);
     203            0 :             querystr = std::string("type.") + ignore_in_2d[n];
     204            0 :             pp.ignore(querystr);
     205            0 :         }
     206              : #endif
     207              :         
     208            0 :     }
     209              : };
     210              : }
     211              : #endif
        

Generated by: LCOV version 2.0-1