From 11d31e5f787d9357f1c153e8cbd55462bffd7e41 Mon Sep 17 00:00:00 2001 From: Weiqun Zhang Date: Thu, 25 Jul 2024 17:37:21 -0700 Subject: [PATCH 1/5] AmrData: remove dependency on Fortran (#4049) This allows us to compile Amrvis without a Fortran compiler. Also removed AmrData::Interp which is never being used anywhere. --- Src/Extern/amrdata/AMReX_AmrData.H | 4 - Src/Extern/amrdata/AMReX_AmrData.cpp | 189 +------ Src/Extern/amrdata/AMReX_FABUTIL_1D.F | 297 ---------- Src/Extern/amrdata/AMReX_FABUTIL_2D.F | 297 ---------- Src/Extern/amrdata/AMReX_FABUTIL_3D.F | 758 -------------------------- Src/Extern/amrdata/CMakeLists.txt | 1 - Src/Extern/amrdata/Make.package | 1 - Tools/CMake/AMReXOptions.cmake | 3 +- 8 files changed, 29 insertions(+), 1521 deletions(-) delete mode 100644 Src/Extern/amrdata/AMReX_FABUTIL_1D.F delete mode 100644 Src/Extern/amrdata/AMReX_FABUTIL_2D.F delete mode 100644 Src/Extern/amrdata/AMReX_FABUTIL_3D.F diff --git a/Src/Extern/amrdata/AMReX_AmrData.H b/Src/Extern/amrdata/AMReX_AmrData.H index e62ce6b1549..dcb9253fdc5 100644 --- a/Src/Extern/amrdata/AMReX_AmrData.H +++ b/Src/Extern/amrdata/AMReX_AmrData.H @@ -16,8 +16,6 @@ namespace amrex { -class Interpolater; - class AmrData { protected: @@ -182,8 +180,6 @@ class AmrData { // fill on interior by piecewise constant interpolation void FillInterior(FArrayBox &dest, int level, const Box &subbox); - void Interp(FArrayBox &fine, FArrayBox &crse, - const Box &fine_box, int lrat); void PcInterp(FArrayBox &fine, const FArrayBox &crse, const Box &subbox, int lrat); FArrayBox *ReadGrid(std::istream &is, int numVar); diff --git a/Src/Extern/amrdata/AMReX_AmrData.cpp b/Src/Extern/amrdata/AMReX_AmrData.cpp index 9717f36a90c..a71d1a6b827 100644 --- a/Src/Extern/amrdata/AMReX_AmrData.cpp +++ b/Src/Extern/amrdata/AMReX_AmrData.cpp @@ -34,73 +34,6 @@ using std::ifstream; #define VSHOWVAL(verbose, val) { if(verbose) { \ cout << #val << " = " << val << endl; } } - -#if defined( BL_FORT_USE_UPPERCASE ) -# if (BL_SPACEDIM == 1) -# define FORT_PCINTERP PCINTERP1D -# elif (BL_SPACEDIM == 2) -# define FORT_CINTERP CINTERP2D -# define FORT_PCINTERP PCINTERP2D -# define FORT_CARTGRIDMINMAX CARTGRIDMINMAX2D -# elif (BL_SPACEDIM == 3) -# define FORT_CINTERP CINTERP3D -# define FORT_PCINTERP PCINTERP3D -# define FORT_CARTGRIDMINMAX CARTGRIDMINMAX3D -# endif -#elif defined( BL_FORT_USE_LOWERCASE ) -# if (BL_SPACEDIM == 1) -# define FORT_PCINTERP pcinterp1d -# elif (BL_SPACEDIM == 2) -# define FORT_CINTERP cinterp2d -# define FORT_PCINTERP pcinterp2d -# define FORT_CARTGRIDMINMAX cartgridminmax2d -# elif (BL_SPACEDIM == 3) -# define FORT_CINTERP cinterp3d -# define FORT_PCINTERP pcinterp3d -# define FORT_CARTGRIDMINMAX cartgridminmax3d -# endif -#else -# if (BL_SPACEDIM == 1) -# define FORT_PCINTERP pcinterp1d_ -# elif (BL_SPACEDIM == 2) -# define FORT_CINTERP cinterp2d_ -# define FORT_PCINTERP pcinterp2d_ -# define FORT_CARTGRIDMINMAX cartgridminmax2d_ -# elif (BL_SPACEDIM == 3) -# define FORT_CINTERP cinterp3d_ -# define FORT_PCINTERP pcinterp3d_ -# define FORT_CARTGRIDMINMAX cartgridminmax3d_ -# endif -#endif - - -extern "C" { -#if (BL_SPACEDIM != 1) - void FORT_CINTERP(amrex::Real *fine, AMREX_ARLIM_P(flo), AMREX_ARLIM_P(fhi), - const int *fblo, const int *fbhi, - const int &nvar, const int &lratio, - const amrex::Real *crse, const int &clo, const int &chi, - const int *cslo, const int *cshi, - const int *fslo, const int *fshi, - amrex::Real *cslope, const int &c_len, - amrex::Real *fslope, amrex::Real *fdat, const int &f_len, - amrex::Real *foff); -#endif - - void FORT_PCINTERP(amrex::Real *fine, AMREX_ARLIM_P(flo), AMREX_ARLIM_P(fhi), - const int *fblo, const int *fbhi, - const int &lrat, const int &nvar, - const amrex::Real *crse, AMREX_ARLIM_P(clo), AMREX_ARLIM_P(chi), - const int *cblo, const int *cbhi, - amrex::Real *temp, const int &tlo, const int &thi); - -#if (BL_SPACEDIM != 1) - void FORT_CARTGRIDMINMAX (amrex::Real *data, AMREX_ARLIM_P(dlo), AMREX_ARLIM_P(dhi), - const amrex::Real *vfrac, const amrex::Real &vfeps, - amrex::Real &dmin, amrex::Real &dmax); -#endif -} - namespace amrex { bool AmrData::verbose = false; @@ -1775,7 +1708,7 @@ bool AmrData::MinMax(const Box &onBox, const string &derived, int level, bool valid(false); // does onBox intersect any grids (are minmax valid) Real minVal, maxVal; dataMin = std::numeric_limits::max(); - dataMax = -std::numeric_limits::max(); + dataMax = std::numeric_limits::lowest(); Box overlap; // our strategy here is to use the VisMF min and maxes if possible @@ -1833,22 +1766,21 @@ bool AmrData::MinMax(const Box &onBox, const string &derived, int level, if(visMFMin < dataMin || visMFMax > dataMax) { // do it the hard way DefineFab(level, compIndex, gdx); DefineFab(level, vfIndex, gdx); - Real *ddat = (*dataGrids[level][compIndex])[gpli].dataPtr(); - Real *vdat = (*dataGrids[level][vfIndex])[gpli].dataPtr(); - const int *dlo = (*dataGrids[level][compIndex])[gpli].loVect(); - const int *dhi = (*dataGrids[level][compIndex])[gpli].hiVect(); - overlap = onBox; overlap &= gpli.validbox(); Real vfMaxVal = (*dataGrids[level][vfIndex])[gpli].max(overlap, 0); if(vfMaxVal >= vfEps[level]) { ++cCountMixedFort; valid = true; - - FORT_CARTGRIDMINMAX(ddat, AMREX_ARLIM(dlo), AMREX_ARLIM(dhi), vdat, vfEps[level], - minVal, maxVal); - dataMin = std::min(dataMin, minVal); - dataMax = std::max(dataMax, maxVal); + auto const& da = (*dataGrids[level][compIndex])[gpli].const_array(); + auto const& va = (*dataGrids[level][vfIndex])[gpli].const_array(); + amrex::LoopOnCpu((*dataGrids[level][compIndex])[gpli].box(), [&] (int i, int j, int k) + { + if (va(i,j,k) >= vfEps[level]) { + dataMin = std::min(dataMin, da(i,j,k)); + dataMax = std::max(dataMax, da(i,j,k)); + } + }); } } else { ++cCountMixedSkipped; @@ -1861,22 +1793,21 @@ bool AmrData::MinMax(const Box &onBox, const string &derived, int level, if(visMFMin < dataMin || visMFMax > dataMax) { // do it the hard way DefineFab(level, compIndex, gdx); DefineFab(level, vfIndex, gdx); - Real *ddat = (*dataGrids[level][compIndex])[gpli].dataPtr(); - Real *vdat = (*dataGrids[level][vfIndex])[gpli].dataPtr(); - const int *dlo = (*dataGrids[level][compIndex])[gpli].loVect(); - const int *dhi = (*dataGrids[level][compIndex])[gpli].hiVect(); - overlap = onBox; overlap &= gpli.validbox(); Real vfMaxVal = (*dataGrids[level][vfIndex])[gpli].max(overlap, 0); if(vfMaxVal >= vfEps[level]) { ++iCountMixedFort; valid = true; - - FORT_CARTGRIDMINMAX(ddat, AMREX_ARLIM(dlo), AMREX_ARLIM(dhi), vdat, vfEps[level], - minVal, maxVal); - dataMin = std::min(dataMin, minVal); - dataMax = std::max(dataMax, maxVal); + auto const& da = (*dataGrids[level][compIndex])[gpli].const_array(); + auto const& va = (*dataGrids[level][vfIndex])[gpli].const_array(); + amrex::LoopOnCpu((*dataGrids[level][compIndex])[gpli].box(), [&] (int i, int j, int k) + { + if (va(i,j,k) >= vfEps[level]) { + dataMin = std::min(dataMin, da(i,j,k)); + dataMax = std::max(dataMax, da(i,j,k)); + } + }); } else { ++iCountAllBody; } @@ -1963,58 +1894,6 @@ int AmrData::StateNumber(const string &statename) const { } -// --------------------------------------------------------------- -void AmrData::Interp(FArrayBox &fine, FArrayBox &crse, - const Box &fine_box, int lrat) -{ -#if (BL_SPACEDIM == 1) - amrex::ignore_unused(fine, crse, fine_box, lrat); - amrex::Abort("AmrData::MinMax: should not be here for 1d."); -#else - BL_ASSERT(fine.box().contains(fine_box)); - Box crse_bx(amrex::coarsen(fine_box,lrat)); - Box fslope_bx(amrex::refine(crse_bx,lrat)); - Box cslope_bx(crse_bx); - cslope_bx.grow(1); - BL_ASSERT(crse.box() == cslope_bx); - - // alloc temp space for coarse grid slopes - Long cLen = cslope_bx.numPts(); - Real *cslope = new Real[BL_SPACEDIM*cLen]; - Long loslp = cslope_bx.index(crse_bx.smallEnd()); - Long hislp = cslope_bx.index(crse_bx.bigEnd()); - Long cslope_vol = cslope_bx.numPts(); - Long clo = 1 - loslp; - Long chi = clo + cslope_vol - 1; - cLen = hislp - loslp + 1; - - // alloc temp space for one strip of fine grid slopes - int dir; - int fLen = fslope_bx.longside(dir); - Real *fdat = new Real[(BL_SPACEDIM+2)*fLen]; - Real *foff = fdat + fLen; - Real *fslope = foff + fLen; - - - // alloc tmp space for slope calc and to allow for vectorization - const int *fblo = fine_box.loVect(); - const int *fbhi = fine_box.hiVect(); - const int *cblo = crse_bx.loVect(); - const int *cbhi = crse_bx.hiVect(); - const int *fslo = fslope_bx.loVect(); - const int *fshi = fslope_bx.hiVect(); - - FORT_CINTERP(fine.dataPtr(0),AMREX_ARLIM(fine.loVect()),AMREX_ARLIM(fine.hiVect()), - fblo,fbhi,fine.nComp(),lrat, - crse.dataPtr(0),clo,chi,cblo,cbhi,fslo,fshi, - cslope,cLen,fslope,fdat,fLen,foff); - - delete [] fdat; - delete [] cslope; -#endif -} - - // --------------------------------------------------------------- void AmrData::PcInterp(FArrayBox &fine, const FArrayBox &crse, const Box &subbox, int lrat) @@ -2026,27 +1905,15 @@ void AmrData::PcInterp(FArrayBox &fine, const FArrayBox &crse, Box fine_ovlp(subbox); fine_ovlp &= cfine; if(fine_ovlp.ok()) { - const int *fblo = fine_ovlp.smallEnd().getVect(); - const int *fbhi = fine_ovlp.bigEnd().getVect(); - Box crse_ovlp(fine_ovlp); - crse_ovlp.coarsen(lrat); - const int *cblo = crse_ovlp.smallEnd().getVect(); - const int *cbhi = crse_ovlp.bigEnd().getVect(); - Box fine_temp(crse_ovlp); - fine_temp.refine(lrat); - int tlo = fine_temp.smallEnd()[0]; - int thi = fine_temp.bigEnd()[0]; - int inextra(0); - if(fine_temp.ixType().test(0) == true) { // node type - inextra = 1; - } - Real *tempSpace = new Real[thi-tlo+1+inextra]; - FORT_PCINTERP(fine.dataPtr(0),AMREX_ARLIM(fine.loVect()),AMREX_ARLIM(fine.hiVect()), - fblo,fbhi, lrat,fine.nComp(), - crse.dataPtr(),AMREX_ARLIM(crse.loVect()),AMREX_ARLIM(crse.hiVect()), - cblo,cbhi, tempSpace,tlo,thi); - - delete [] tempSpace; + auto const& fa = fine.array(); + auto const& ca = crse.const_array(); + amrex::LoopOnCpu(fine_ovlp, fine.nComp(), [&] (int i, int j, int k, int n) + { + int ic = amrex::coarsen(i,lrat); + int jc = amrex::coarsen(j,lrat); + int kc = amrex::coarsen(k,lrat); + fa(i,j,k,n) = ca(ic,jc,kc,n); + }); } } diff --git a/Src/Extern/amrdata/AMReX_FABUTIL_1D.F b/Src/Extern/amrdata/AMReX_FABUTIL_1D.F deleted file mode 100644 index 42824b08963..00000000000 --- a/Src/Extern/amrdata/AMReX_FABUTIL_1D.F +++ /dev/null @@ -1,297 +0,0 @@ -c ::: SCCS stuff "@(#)FABUTIL_2D.F 3.1\t6/25/93" - -#define FORT_CINTERP cinterp1d -#define FORT_PCINTERP pcinterp1d - -#include "AMReX_REAL.H" - -#ifdef BL_USE_FLOAT -#define REAL_T real -#define bigreal 1.0e30 -#define zero 0.0e0 -#define one 1.0e0 -#define half 0.5e0 -#else -#define REAL_T double precision -#define bigreal 1.0d30 -#define zero 0.0d0 -#define one 1.0d0 -#define half 0.5d0 -#endif - -c ::: -------------------------------------------------------------- - subroutine FORT_CINTERP (fine,floi1,floi2,fhii1,fhii2, fblo,fbhi, - $ nvar,lratio, crse,clo,chi,cblo,cbhi,fslo,fshi, cslope,clen, - $ fslope,fdat,flen,voff) - - implicit none - - integer floi1,floi2, fhii1,fhii2 - - integer fblo(2), fbhi(2) - integer cblo(2), cbhi(2) - integer fslo(2), fshi(2) - integer lratio, nvar, clen, flen, clo, chi - REAL_T fine(floi1 :fhii1 ,floi2 :fhii2, nvar) - REAL_T crse(clo:chi, nvar) - REAL_T cslope(clo:chi, 2) - REAL_T fslope(flen, 2) - REAL_T fdat(flen) - REAL_T voff(flen) - -c ::: NOTE: data must be sent in so that -c ::: cslope(1,*) and crse(1,*) are associated with -c ::: the same cell - -c ::: :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -c ::: cinterp: conservative interpolation from coarse grid to -c ::: subregion of fine grid defined by (fblo,fbhi) -c ::: -c ::: Inputs/Outputs -c ::: fine <=> (modify) fine grid array -c ::: flo,fhi => (const) index limits of fine grid -c ::: fblo,fbhi => (const) subregion of fine grid to get values -c ::: nvar => (const) number of variables in state vector -c ::: lratio => (const) refinement ratio between levels -c ::: -c ::: crse => (const) coarse grid data widended by 1 zone -c ::: and unrolled -c ::: clo,chi => (const) one dimensional limits of crse grid -c ::: cslo,cshi => (const) coarse grid index limits where -c ::: slopes are to be defined. This is -c ::: the projection of (fblo,fbhi) down -c ::: to the coarse level -c ::: fslo,fshi => (const) fine grid index limits where -c ::: slopes are needed. This is the -c ::: refinement of (cslo,cshi) and -c ::: contains but may not be identical -c ::: to (fblo,fbhi). -c ::: cslope => (modify) temp array coarse grid slopes -c ::: clen => (const) length of coarse gtid slopes -c ::: fslope => (modify) temp array for fine grid slope -c ::: flen => (const) length of fine grid slope array -c ::: fdat => (const) temp array for fine grid data -c ::: :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: - -c ::: local var - integer n, fn - integer i, ic, ioff - integer j, jc, joff - integer ist, jst - REAL_T hafrat, volratio - REAL_T cen, forw, back, slp - REAL_T xoff, yoff - integer ncbx, ncby - integer ncsx, ncsy - integer islo, jslo - integer icc, istart, iend - integer lenx, leny, maxlen - - call bl_abort("fix FORT_CINTERP for 1d.") - - hafrat = half*float(lratio-1) - volratio = one/float(lratio) - - ncbx = cbhi(1)-cblo(1)+1 - ncby = cbhi(2)-cblo(2)+1 - ncsx = ncbx+2 - ncsy = ncby+2 - ist = 1 - jst = ncsx - islo = cblo(1)-1 - jslo = cblo(2)-1 - lenx = fbhi(1)-fblo(1)+1 - leny = fbhi(2)-fblo(2)+1 - maxlen = max(lenx,leny) - if (maxlen .eq. lenx) then - do 100 i = fblo(1), fbhi(1) - fn = i-fslo(1)+1 - ioff = mod(fn-1,lratio) - voff(fn) = float(ioff)-hafrat -100 continue - else - do 110 j = fblo(2), fbhi(2) - fn = j-fslo(2)+1 - joff = mod(fn-1,lratio) - voff(fn) = float(joff)-hafrat -110 continue - end if - do 120 n = 1, nvar - -c ::: ::::: compute slopes in x direction - do 130 i = 1, clen - cen = half*(crse(i+ist,n)-crse(i-ist,n)) - forw = crse(i+ist,n)-crse(i,n) - back = crse(i,n)-crse(i-ist,n) - slp = sign(one,cen)*min(abs(cen),abs(forw),abs(back)) - cslope(i,1)=merge(slp,zero,forw*back>=0.0d0) -130 continue -c ::: ::::: compute slopes in y direction - do 140 i = 1, clen - cen = half*(crse(i+jst,n)-crse(i-jst,n)) - forw = crse(i+jst,n)-crse(i,n) - back = crse(i,n)-crse(i-jst,n) - slp = sign(one,cen)*min(abs(cen),abs(forw),abs(back)) - cslope(i,2)=merge(slp,zero,forw*back>=0.0d0) -140 continue - if (maxlen .eq. lenx) then - do 150 jc = cblo(2), cbhi(2) - -c ::: ..,.......::::: strip out a fine grid slope vector - do 160 ioff = 1, lratio - icc = clo + ist + jst*(jc-jslo) - istart = ioff - iend = ioff + (ncbx-1)*lratio - do 170 fn = istart, iend, lratio - fslope(fn,1) = cslope(icc,1) - fslope(fn,2) = cslope(icc,2) - fdat(fn) = crse(icc,n) - icc = icc + ist -170 continue -160 continue - - do 180 joff = 0, lratio-1 - j = lratio*jc + joff - if (j .lt. fblo(2)) then - goto 180 -c --- next --- - end if - if (j .gt. fbhi(2)) then - goto 181 -c --- break --- - end if - yoff = float(joff)-hafrat - - do 190 i = fblo(1), fbhi(1) - fn = i-fslo(1)+1 - fine(i,j,n) = fdat(fn) + volratio* (voff(fn)* - $ fslope(fn,1)+yoff*fslope(fn,2)) -190 continue -180 continue -181 continue -150 continue - else - do 200 ic = cblo(1), cbhi(1) - -c ::: ..,.......::::: strip out a fine grid slope vector - do 210 joff = 1, lratio - icc = clo + ist*(ic-islo) + jst - istart = joff - iend = joff + (ncby-1)*lratio - do 220 fn = istart, iend, lratio - fslope(fn,1) = cslope(icc,1) - fslope(fn,2) = cslope(icc,2) - fdat(fn) = crse(icc,n) - icc = icc + jst -220 continue -210 continue - - do 230 ioff = 0, lratio-1 - i = lratio*ic + ioff - if (i .lt. fblo(1)) then - goto 230 -c --- next --- - end if - if (i .gt. fbhi(1)) then - goto 231 -c --- break --- - end if - xoff = float(ioff)-hafrat - - do 240 j = fblo(2), fbhi(2) - fn = j-fslo(2)+1 - fine(i,j,n) = fdat(fn) + volratio* (xoff* - $ fslope(fn,1)+voff(fn)*fslope(fn,2)) -240 continue -230 continue -231 continue -200 continue - end if -120 continue - - return - end - - -c ::: -------------------------------------------------------------- - subroutine FORT_PCINTERP (fine,floi1,fhii1,fblo, fbhi,lrat, - $ nvar, crse,cloi1,chii1,cblo, cbhi,temp,tloi,thii) - - implicit none - - integer floi1 - integer fhii1 - integer cloi1 - integer chii1 - - integer fblo(1), fbhi(1) - integer cblo(1), cbhi(1) - integer lrat, nvar, tloi, thii - REAL_T fine(floi1 :fhii1, nvar) - REAL_T crse(cloi1 :chii1, nvar) - REAL_T temp(tloi:thii + 1) -c ::: :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -c ::: pcinterp: use piecewise constant interpolation to define -c ::: values on the subregion of the fine FAB defined -c ::: by (fblo,fbhi). -c ::: -c ::: Inputs/Outputs -c ::: fine <=> (modify) fab to get interpolated values -c ::: flo,fhi => (const) index limits of fine -c ::: fblo,fbhi => (const) subregion of fine grid to get values -c ::: crse => (const) fab holding coarse grid values -c ::: clo,chi => (const) index limits of src -c ::: cblo,cbhi => (const) subregion of coarse grid holding values -c ::: temp => (modify) temporary space for vectorization -c ::: tlo,thi => (const) index limits of temp space -c ::: :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -c ::: local var - integer i,ic,ioff,n - integer ixproj,ii,ll - ixproj(ii,ll) = (ii + ll*iabs(ii))/ll - iabs(ii) - - do 130 n = 1, nvar - do 140 ioff = 0, lrat-1 - do 150 ic = cblo(1),cbhi(1) - i = lrat*ic + ioff - temp(i) = crse(ic,n) -150 continue -140 continue - do 160 i = fblo(1), fbhi(1) - fine(i,n) = temp(i) -160 continue -130 continue - - return - end - - -c ::: -------------------------------------------------------------- - subroutine cartgridminmax1d (data, lo1, lo2, hi1, hi2, - $ vfracdata, vfeps, dmin, dmax) - implicit none - - integer lo1, lo2, hi1, hi2 - REAL_T data(lo1:hi1 ,lo2:hi2) - REAL_T vfracdata(lo1:hi1 ,lo2:hi2) - REAL_T vfeps, dmin, dmax - - integer i, j - - call bl_abort("fix cartgridminmax1d for 1d.") - - dmax = -bigreal - dmin = bigreal - do 420 j = lo2, hi2 - do 430 i = lo1, hi1 -c print *, "i j vfracdata(i,j) = ",i,j,vfracdata(i,j) - if ( .not. (vfracdata(i,j).lt.vfeps)) then - dmax = max(dmax,data(i,j)) - dmin = min(dmin,data(i,j)) - endif -430 continue -420 continue - - return - end - diff --git a/Src/Extern/amrdata/AMReX_FABUTIL_2D.F b/Src/Extern/amrdata/AMReX_FABUTIL_2D.F deleted file mode 100644 index 8748760ff35..00000000000 --- a/Src/Extern/amrdata/AMReX_FABUTIL_2D.F +++ /dev/null @@ -1,297 +0,0 @@ -c ::: SCCS stuff "@(#)FABUTIL_2D.F 3.1\t6/25/93" - -#define FORT_CINTERP cinterp2d -#define FORT_PCINTERP pcinterp2d - -#include "AMReX_REAL.H" - -#ifdef BL_USE_FLOAT -#define REAL_T real -#define bigreal 1.0e30 -#define zero 0.0e0 -#define one 1.0e0 -#define half 0.5e0 -#else -#define REAL_T double precision -#define bigreal 1.0d30 -#define zero 0.0d0 -#define one 1.0d0 -#define half 0.5d0 -#endif - -c ::: -------------------------------------------------------------- - subroutine FORT_CINTERP (fine,floi1,floi2,fhii1,fhii2, fblo,fbhi, - $ nvar,lratio, crse,clo,chi,cblo,cbhi,fslo,fshi, cslope,clen, - $ fslope,fdat,flen,voff) - - implicit none - - integer floi1,floi2, fhii1,fhii2 - - integer fblo(2), fbhi(2) - integer cblo(2), cbhi(2) - integer fslo(2), fshi(2) - integer lratio, nvar, clen, flen, clo, chi - REAL_T fine(floi1 :fhii1 ,floi2 :fhii2, nvar) - REAL_T crse(clo:chi, nvar) - REAL_T cslope(clo:chi, 2) - REAL_T fslope(flen, 2) - REAL_T fdat(flen) - REAL_T voff(flen) - -c ::: NOTE: data must be sent in so that -c ::: cslope(1,*) and crse(1,*) are associated with -c ::: the same cell - -c ::: :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -c ::: cinterp: conservative interpolation from coarse grid to -c ::: subregion of fine grid defined by (fblo,fbhi) -c ::: -c ::: Inputs/Outputs -c ::: fine <=> (modify) fine grid array -c ::: flo,fhi => (const) index limits of fine grid -c ::: fblo,fbhi => (const) subregion of fine grid to get values -c ::: nvar => (const) number of variables in state vector -c ::: lratio => (const) refinement ratio between levels -c ::: -c ::: crse => (const) coarse grid data widended by 1 zone -c ::: and unrolled -c ::: clo,chi => (const) one dimensional limits of crse grid -c ::: cslo,cshi => (const) coarse grid index limits where -c ::: slopes are to be defined. This is -c ::: the projection of (fblo,fbhi) down -c ::: to the coarse level -c ::: fslo,fshi => (const) fine grid index limits where -c ::: slopes are needed. This is the -c ::: refinement of (cslo,cshi) and -c ::: contains but may not be identical -c ::: to (fblo,fbhi). -c ::: cslope => (modify) temp array coarse grid slopes -c ::: clen => (const) length of coarse gtid slopes -c ::: fslope => (modify) temp array for fine grid slope -c ::: flen => (const) length of fine grid slope array -c ::: fdat => (const) temp array for fine grid data -c ::: :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: - -c ::: local var - integer n, fn - integer i, ic, ioff - integer j, jc, joff - integer ist, jst - REAL_T hafrat, volratio - REAL_T cen, forw, back, slp - REAL_T xoff, yoff - integer ncbx, ncby - integer ncsx, ncsy - integer islo, jslo - integer icc, istart, iend - integer lenx, leny, maxlen - - hafrat = half*float(lratio-1) - volratio = one/float(lratio) - - ncbx = cbhi(1)-cblo(1)+1 - ncby = cbhi(2)-cblo(2)+1 - ncsx = ncbx+2 - ncsy = ncby+2 - ist = 1 - jst = ncsx - islo = cblo(1)-1 - jslo = cblo(2)-1 - lenx = fbhi(1)-fblo(1)+1 - leny = fbhi(2)-fblo(2)+1 - maxlen = max(lenx,leny) - if (maxlen .eq. lenx) then - do 100 i = fblo(1), fbhi(1) - fn = i-fslo(1)+1 - ioff = mod(fn-1,lratio) - voff(fn) = float(ioff)-hafrat -100 continue - else - do 110 j = fblo(2), fbhi(2) - fn = j-fslo(2)+1 - joff = mod(fn-1,lratio) - voff(fn) = float(joff)-hafrat -110 continue - end if - do 120 n = 1, nvar - -c ::: ::::: compute slopes in x direction - do 130 i = 1, clen - cen = half*(crse(i+ist,n)-crse(i-ist,n)) - forw = crse(i+ist,n)-crse(i,n) - back = crse(i,n)-crse(i-ist,n) - slp = sign(one,cen)*min(abs(cen),abs(forw),abs(back)) - cslope(i,1)=merge(slp,zero,forw*back>=0.0d0) -130 continue -c ::: ::::: compute slopes in y direction - do 140 i = 1, clen - cen = half*(crse(i+jst,n)-crse(i-jst,n)) - forw = crse(i+jst,n)-crse(i,n) - back = crse(i,n)-crse(i-jst,n) - slp = sign(one,cen)*min(abs(cen),abs(forw),abs(back)) - cslope(i,2)=merge(slp,zero,forw*back>=0.0d0) -140 continue - if (maxlen .eq. lenx) then - do 150 jc = cblo(2), cbhi(2) - -c ::: ..,.......::::: strip out a fine grid slope vector - do 160 ioff = 1, lratio - icc = clo + ist + jst*(jc-jslo) - istart = ioff - iend = ioff + (ncbx-1)*lratio - do 170 fn = istart, iend, lratio - fslope(fn,1) = cslope(icc,1) - fslope(fn,2) = cslope(icc,2) - fdat(fn) = crse(icc,n) - icc = icc + ist -170 continue -160 continue - - do 180 joff = 0, lratio-1 - j = lratio*jc + joff - if (j .lt. fblo(2)) then - goto 180 -c --- next --- - end if - if (j .gt. fbhi(2)) then - goto 181 -c --- break --- - end if - yoff = float(joff)-hafrat - - do 190 i = fblo(1), fbhi(1) - fn = i-fslo(1)+1 - fine(i,j,n) = fdat(fn) + volratio* (voff(fn)* - $ fslope(fn,1)+yoff*fslope(fn,2)) -190 continue -180 continue -181 continue -150 continue - else - do 200 ic = cblo(1), cbhi(1) - -c ::: ..,.......::::: strip out a fine grid slope vector - do 210 joff = 1, lratio - icc = clo + ist*(ic-islo) + jst - istart = joff - iend = joff + (ncby-1)*lratio - do 220 fn = istart, iend, lratio - fslope(fn,1) = cslope(icc,1) - fslope(fn,2) = cslope(icc,2) - fdat(fn) = crse(icc,n) - icc = icc + jst -220 continue -210 continue - - do 230 ioff = 0, lratio-1 - i = lratio*ic + ioff - if (i .lt. fblo(1)) then - goto 230 -c --- next --- - end if - if (i .gt. fbhi(1)) then - goto 231 -c --- break --- - end if - xoff = float(ioff)-hafrat - - do 240 j = fblo(2), fbhi(2) - fn = j-fslo(2)+1 - fine(i,j,n) = fdat(fn) + volratio* (xoff* - $ fslope(fn,1)+voff(fn)*fslope(fn,2)) -240 continue -230 continue -231 continue -200 continue - end if -120 continue - - return - end - - -c ::: -------------------------------------------------------------- - subroutine FORT_PCINTERP (fine,floi1,floi2,fhii1,fhii2,fblo, - $ fbhi,lrat,nvar,crse,cloi1,cloi2,chii1,chii2,cblo, - $ cbhi,temp,tloi,thii) - - implicit none - - integer floi1,floi2 - integer fhii1,fhii2 - integer cloi1,cloi2 - integer chii1,chii2 - - integer fblo(2), fbhi(2) - integer cblo(2), cbhi(2) - integer lrat, nvar, tloi, thii - REAL_T fine(floi1 :fhii1 ,floi2 :fhii2, nvar) - REAL_T crse(cloi1 :chii1 ,cloi2 :chii2, nvar) - REAL_T temp(tloi:thii + 1) -c ::: :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -c ::: pcinterp: use piecewise constant interpolation to define -c ::: values on the subregion of the fine FAB defined -c ::: by (fblo,fbhi). -c ::: -c ::: Inputs/Outputs -c ::: fine <=> (modify) fab to get interpolated values -c ::: flo,fhi => (const) index limits of fine -c ::: fblo,fbhi => (const) subregion of fine grid to get values -c ::: crse => (const) fab holding coarse grid values -c ::: clo,chi => (const) index limits of src -c ::: cblo,cbhi => (const) subregion of coarse grid holding values -c ::: temp => (modify) temporary space for vectorization -c ::: tlo,thi => (const) index limits of temp space -c ::: :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -c ::: local var - integer i,j,k,ic,jc,kc,ioff,n - integer ixproj,ii,ll - ixproj(ii,ll) = (ii + ll*iabs(ii))/ll - iabs(ii) - - do 120 j = fblo(2), fbhi(2) - jc = ixproj(j,lrat) - do 130 n = 1, nvar - do 140 ioff = 0, lrat-1 - do 150 ic = cblo(1),cbhi(1) - i = lrat*ic + ioff - temp(i) = crse(ic,jc,n) -150 continue -140 continue - do 160 i = fblo(1), fbhi(1) - fine(i,j,n) = temp(i) -160 continue -130 continue -120 continue - - return - end - - -c ::: -------------------------------------------------------------- - subroutine cartgridminmax2d (data, lo1, lo2, hi1, hi2, - $ vfracdata, vfeps, dmin, dmax) - implicit none - - integer lo1, lo2, hi1, hi2 - REAL_T data(lo1:hi1 ,lo2:hi2) - REAL_T vfracdata(lo1:hi1 ,lo2:hi2) - REAL_T vfeps, dmin, dmax - - integer i, j - - dmax = -bigreal - dmin = bigreal - do 420 j = lo2, hi2 - do 430 i = lo1, hi1 -c print *, "i j vfracdata(i,j) = ",i,j,vfracdata(i,j) - if ( .not. (vfracdata(i,j).lt.vfeps)) then - dmax = max(dmax,data(i,j)) - dmin = min(dmin,data(i,j)) - endif -430 continue -420 continue - - return - end - diff --git a/Src/Extern/amrdata/AMReX_FABUTIL_3D.F b/Src/Extern/amrdata/AMReX_FABUTIL_3D.F deleted file mode 100644 index 8a6ff561577..00000000000 --- a/Src/Extern/amrdata/AMReX_FABUTIL_3D.F +++ /dev/null @@ -1,758 +0,0 @@ -c ::: SCCS stuff "@(#)FABUTIL_3D.F 3.1\t6/25/93" - -#define FORT_CINTERP cinterp3d -#define FORT_PCINTERP pcinterp3d -#define FORT_VCINTERP vcinterp3d -#define FORT_CARTGRIDMINMAX cartgridminmax3d - -#include "AMReX_REAL.H" - -#ifdef BL_USE_FLOAT -#define REAL_T real -#define bigreal 1.0e30 -#define zero 0.0e0 -#define one 1.0e0 -#define half 0.5e0 -#else -#define REAL_T double precision -#define bigreal 1.0d30 -#define zero 0.0d0 -#define one 1.0d0 -#define half 0.5d0 -#endif - -#define IX_PROJ(A,B) (A+B*iabs(A))/B-iabs(A) - - -c ::: -------------------------------------------------------------- - subroutine FORT_CARTGRIDMINMAX (data, dlo1, dlo2, dlo3, dhi1, - $ dhi2, dhi3, vfracdata, vfeps, - $ dmin, dmax) - implicit none - - integer dlo1, dlo2, dlo3, dhi1, dhi2, dhi3 - REAL_T data(dlo1:dhi1 ,dlo2:dhi2, dlo3:dhi3) - REAL_T vfracdata(dlo1:dhi1 ,dlo2:dhi2, dlo3:dhi3) - REAL_T vfeps, dmin, dmax - - integer i, j, k - - dmax = -bigreal - dmin = bigreal - do 410 k = dlo3, dhi3 - do 420 j = dlo2, dhi2 - do 430 i = dlo1, dhi1 - if ( (vfracdata(i,j,k).ge.vfeps)) then - dmax = max(dmax,data(i,j,k)) - dmin = min(dmin,data(i,j,k)) - endif -430 continue -420 continue -410 continue - - return - end - - -c ::: -------------------------------------------------------------- - subroutine FORT_CINTERP (fine,floi1,floi2,floi3,fhii1,fhii2,fhii3, - $ fblo,fbhi,nvar,lratio, crse,clo,chi,cblo,cbhi,fslo,fshi, cslope, - $ clen,fslope,fdat,flen,voff) - - implicit none - - integer floi1,floi2,floi3, fhii1,fhii2,fhii3 - integer fblo(3), fbhi(3) - integer cblo(3), cbhi(3) - integer fslo(3), fshi(3) - integer lratio, nvar, clen, flen, clo, chi - REAL_T fine(floi1:fhii1,floi2:fhii2,floi3:fhii3,nvar) - REAL_T crse(clo:chi, nvar) - REAL_T cslope(clo:chi, 3) - REAL_T fslope(flen, 3) - REAL_T fdat(flen) - REAL_T voff(flen) - -c ::: NOTE: data must be sent in so that -c ::: cslope(1,*) and crse(1,*) are associated with -c ::: the same cell - -c ::: :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -c ::: cinterp: conservative interpolation from coarse grid to -c ::: subregion of fine grid defined by (fblo,fbhi) -c ::: -c ::: Inputs/Outputs -c ::: fine <=> (modify) fine grid array -c ::: flo,fhi => (const) index limits of fine grid -c ::: fblo,fbhi => (const) subregion of fine grid to get values -c ::: nvar => (const) number of variables in state vector -c ::: lratio => (const) refinement ratio between levels -c ::: -c ::: crse => (const) coarse grid data widended by 1 zone -c ::: and unrolled -c ::: clo,chi => (const) one dimensional limits of crse grid -c ::: cslo,cshi => (const) coarse grid index limits where -c ::: slopes are to be defined. This is -c ::: the projection of (fblo,fbhi) down -c ::: to the coarse level -c ::: fslo,fshi => (const) fine grid index limits where -c ::: slopes are needed. This is the -c ::: refinement of (cslo,cshi) and -c ::: contains but may not be identical -c ::: to (fblo,fbhi). -c ::: cslope => (modify) temp array coarse grid slopes -c ::: clen => (const) length of coarse gtid slopes -c ::: fslope => (modify) temp array for fine grid slope -c ::: flen => (const) length of fine grid slope array -c ::: fdat => (const) temp array for fine grid data -c ::: :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: - -c ::: local var - integer n, fn - integer i, ic, ioff - integer j, jc, joff - integer k, kc, koff - integer ist, jst, kst - REAL_T hafrat, volratio - REAL_T cen, forw, back, slp - REAL_T xoff, yoff, zoff - integer ncbx, ncby, ncbz - integer ncsx, ncsy, ncsz - integer islo, jslo, kslo - integer icc, istart, iend - integer lenx, leny, lenz, maxlen - - hafrat = half*float(lratio-1) - volratio = one/float(lratio) - - ncbx = cbhi(1)-cblo(1)+1 - ncby = cbhi(2)-cblo(2)+1 - ncbz = cbhi(3)-cblo(3)+1 - ncsx = ncbx+2 - ncsy = ncby+2 - ncsz = ncbz+2 - ist = 1 - jst = ncsx - kst = ncsx*ncsy - islo = cblo(1)-1 - jslo = cblo(2)-1 - kslo = cblo(3)-1 - lenx = fbhi(1)-fblo(1)+1 - leny = fbhi(2)-fblo(2)+1 - lenz = fbhi(3)-fblo(3)+1 - maxlen = max(lenx,leny,lenz) - if (maxlen .eq. lenx) then - do 100 i = fblo(1), fbhi(1) - fn = i-fslo(1)+1 - ioff = mod(fn-1,lratio) - voff(fn) = float(ioff)-hafrat -100 continue - else if (maxlen .eq. leny) then - do 110 j = fblo(2), fbhi(2) - fn = j-fslo(2)+1 - joff = mod(fn-1,lratio) - voff(fn) = float(joff)-hafrat -110 continue - else - do 120 k = fblo(3), fbhi(3) - fn = k-fslo(3)+1 - koff = mod(fn-1,lratio) - voff(fn) = float(koff)-hafrat -120 continue - end if - do 130 n = 1, nvar - -c ::: ::::: compute slopes in x direction - do 140 i = 1, clen - cen = half*(crse(i+ist,n)-crse(i-ist,n)) - forw = crse(i+ist,n)-crse(i,n) - back = crse(i,n)-crse(i-ist,n) - slp = sign(one,cen)*min(abs(cen),abs(forw),abs(back)) - cslope(i,1)=merge(slp,zero,forw*back>=0.0d0) -140 continue -c ::: ::::: compute slopes in y direction - do 150 i = 1, clen - cen = half*(crse(i+jst,n)-crse(i-jst,n)) - forw = crse(i+jst,n)-crse(i,n) - back = crse(i,n)-crse(i-jst,n) - slp = sign(one,cen)*min(abs(cen),abs(forw),abs(back)) - cslope(i,2)=merge(slp,zero,forw*back>=0.0d0) -150 continue -c ::: ::::: compute slopes in z direction - do 160 i = 1, clen - cen = half*(crse(i+kst,n)-crse(i-kst,n)) - forw = crse(i+kst,n)-crse(i,n) - back = crse(i,n)-crse(i-kst,n) - slp = sign(one,cen)*min(abs(cen),abs(forw),abs(back)) - cslope(i,3)=merge(slp,zero,forw*back>=0.0d0) -160 continue - - if (maxlen .eq. lenx) then - do 170 kc = cblo(3), cbhi(3) - do 180 jc = cblo(2), cbhi(2) - -c ::: ..,.......::::: strip out a fine grid slope vector - do 190 ioff = 1, lratio - icc = clo + ist + jst*(jc-jslo) + kst*(kc- - $ kslo) - istart = ioff - iend = ioff + (ncbx-1)*lratio - do 200 fn = istart, iend, lratio - fslope(fn,1) = cslope(icc,1) - fslope(fn,2) = cslope(icc,2) - fslope(fn,3) = cslope(icc,3) - fdat(fn) = crse(icc,n) - icc = icc + ist -200 continue -190 continue - - do 210 koff = 0, lratio-1 - k = lratio*kc + koff - if (k .lt. fblo(3)) then - goto 210 -c --- next --- - end if - if (k .gt. fbhi(3)) then - goto 211 -c --- break --- - end if - zoff = float(koff)-hafrat - do 220 joff = 0, lratio-1 - j = lratio*jc + joff - if (j .lt. fblo(2)) then - goto 220 -c --- next --- - end if - if (j .gt. fbhi(2)) then - goto 221 -c --- break --- - end if - yoff = float(joff)-hafrat - - do 230 i = fblo(1), fbhi(1) - fn = i-fslo(1)+1 - fine(i,j,k,n) = fdat(fn) + volratio* - $ (voff(fn)*fslope(fn,1)+yoff*fslope(fn, - $ 2)+ zoff*fslope(fn,3)) -230 continue -220 continue -221 continue -210 continue -211 continue -180 continue -170 continue - else if (maxlen .eq. leny) then - do 240 kc = cblo(3), cbhi(3) - do 250 ic = cblo(1), cbhi(1) - -c ::: ..,.......::::: strip out a fine grid slope vector - do 260 joff = 1, lratio - icc = clo + ist*(ic-islo) + jst + kst*(kc- - $ kslo) - istart = joff - iend = joff + (ncby-1)*lratio - do 270 fn = istart, iend, lratio - fslope(fn,1) = cslope(icc,1) - fslope(fn,2) = cslope(icc,2) - fslope(fn,3) = cslope(icc,3) - fdat(fn) = crse(icc,n) - icc = icc + jst -270 continue -260 continue - - do 280 koff = 0, lratio-1 - k = lratio*kc + koff - if (k .lt. fblo(3)) then - goto 280 -c --- next --- - end if - if (k .gt. fbhi(3)) then - goto 281 -c --- break --- - end if - zoff = float(koff)-hafrat - do 290 ioff = 0, lratio-1 - i = lratio*ic + ioff - if (i .lt. fblo(1)) then - goto 290 -c --- next --- - end if - if (i .gt. fbhi(1)) then - goto 291 -c --- break --- - end if - xoff = float(ioff)-hafrat - - do 300 j = fblo(2), fbhi(2) - fn = j-fslo(2)+1 - fine(i,j,k,n) = fdat(fn) + volratio* - $ (xoff*fslope(fn,1)+voff(fn)*fslope(fn, - $ 2)+ zoff*fslope(fn,3)) -300 continue -290 continue -291 continue -280 continue -281 continue -250 continue -240 continue - else - do 310 jc = cblo(2), cbhi(2) - do 320 ic = cblo(1), cbhi(1) - -c ::: ..,.......::::: strip out a fine grid slope vector - do 330 koff = 1, lratio - icc = clo + ist*(ic-islo) + jst*(jc-jslo) + - $ kst - istart = koff - iend = koff + (ncbz-1)*lratio - do 340 fn = istart, iend, lratio - fslope(fn,1) = cslope(icc,1) - fslope(fn,2) = cslope(icc,2) - fslope(fn,3) = cslope(icc,3) - fdat(fn) = crse(icc,n) - icc = icc + kst -340 continue -330 continue - - do 350 joff = 0, lratio-1 - j = lratio*jc + joff - if (j .lt. fblo(2)) then - goto 350 -c --- next --- - end if - if (j .gt. fbhi(2)) then - goto 351 -c --- break --- - end if - yoff = float(joff)-hafrat - do 360 ioff = 0, lratio-1 - i = lratio*ic + ioff - if (i .lt. fblo(1)) then - goto 360 -c --- next --- - end if - if (i .gt. fbhi(1)) then - goto 361 -c --- break --- - end if - xoff = float(ioff)-hafrat - - do 370 k = fblo(3), fbhi(3) - fn = k-fslo(3)+1 - fine(i,j,k,n) = fdat(fn) + volratio* - $ (xoff*fslope(fn,1)+yoff*fslope(fn,2)+ - $ voff(fn)*fslope(fn,3)) -370 continue -360 continue -361 continue -350 continue -351 continue -320 continue -310 continue - end if -130 continue - - return - end - - -c ::: -------------------------------------------------------------- - subroutine FORT_PCINTERP (fine,floi1,floi2,floi3,fhii1,fhii2, - $ fhii3,fblo,fbhi,lrat,nvar,crse,cloi1,cloi2,cloi3,chii1,chii2, - $ chii3,cblo,cbhi,temp,tloi,thii) - - implicit none - - integer floi1,floi2,floi3 - integer fhii1,fhii2,fhii3 - integer cloi1,cloi2,cloi3 - integer chii1,chii2,chii3 - - integer fblo(3), fbhi(3) - integer cblo(3), cbhi(3) - integer lrat, nvar, tloi, thii - REAL_T fine(floi1:fhii1,floi2:fhii2,floi3:fhii3, nvar) - REAL_T crse(cloi1:chii1,cloi2:chii2,cloi3:chii3, nvar) - REAL_T temp(tloi:thii + 1) -c ::: :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -c ::: pcinterp: use piecewise constant interpolation to define -c ::: values on the subregion of the fine FAB defined -c ::: by (fblo,fbhi). -c ::: -c ::: Inputs/Outputs -c ::: fine <=> (modify) fab to get interpolated values -c ::: flo,fhi => (const) index limits of fine -c ::: fblo,fbhi => (const) subregion of fine grid to get values -c ::: crse => (const) fab holding coarse grid values -c ::: clo,chi => (const) index limits of src -c ::: cblo,cbhi => (const) subregion of coarse grid holding values -c ::: temp => (modify) temporary space for vectorization -c ::: tlo,thi => (const) index limits of temp space -c ::: :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -c ::: local var - integer i,j,k,ic,jc,kc,ioff,n - integer ixproj,ii,ll - ixproj(ii,ll) = (ii + ll*iabs(ii))/ll - iabs(ii) - - do 130 k = fblo(3), fbhi(3) - kc = ixproj(k,lrat) - do 140 j = fblo(2), fbhi(2) - jc = ixproj(j,lrat) - do 150 n = 1, nvar - do 160 ioff = 0, lrat-1 - do 170 ic = cblo(1),cbhi(1) - i = lrat*ic + ioff - temp(i) = crse(ic,jc,kc,n) -170 continue -160 continue - do 180 i = fblo(1), fbhi(1) - fine(i,j,k,n) = temp(i) -180 continue -150 continue -140 continue -130 continue - - return - end - - -c ::: -------------------------------------------------------------- - subroutine FORT_VCINTERP (fine,floi1,floi2,floi3,fhii1,fhii2, - $ fhii3,fbloi1,fbloi2,fbloi3, fbhii1,fbhii2,fbhii3,nvar,lratio, - $ crse,clo,chi,cblo,cbhi, fslo,fshi,cvloi1,cvloi2,cvloi3,cvhii1, - $ cvhii2,cvhii3, cslope,clen,fslope,fdat,flen,voff, cvc1,fvc1,cvc2, - $ fvc2,cvc3,fvc3) - - implicit none - - integer floi1,floi2,floi3 - integer fhii1,fhii2,fhii3 - integer fbloi1,fbloi2,fbloi3 - integer fbhii1,fbhii2,fbhii3 - integer cvloi1,cvloi2,cvloi3 - integer cvhii1,cvhii2,cvhii3 - - integer cblo(3), cbhi(3) - integer fslo(3), fshi(3) - integer lratio, nvar, clen, flen, clo, chi - REAL_T fine(floi1:fhii1,floi2:fhii2,floi3:fhii3,nvar) - REAL_T crse(clo:chi, nvar) - REAL_T cslope(clo:chi, 3) - REAL_T fslope(flen, 3) - REAL_T fdat(flen) - REAL_T voff(flen) - - REAL_T cvc1(cvloi1 :cvhii1+1) - REAL_T cvc2(cvloi2 :cvhii2+1) - REAL_T cvc3(cvloi3 :cvhii3+1) - REAL_T fvc1(fbloi1 :fbhii1+1) - REAL_T fvc2(fbloi2 :fbhii2+1) - REAL_T fvc3(fbloi3 :fbhii3+1) - -c ::: NOTE: data must be sent in so that -c ::: cslope(1,*) and crse(1,*) are associated with -c ::: the same cell - -c ::: :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -c ::: vcinterp: conservative interpolation in volume coordinates -c ::: from coarse grid to -c ::: subregion of fine grid defined by (fblo,fbhi) -c ::: -c ::: Inputs/Outputs -c ::: fine <=> (modify) fine grid array -c ::: flo,fhi => (const) index limits of fine grid -c ::: fblo,fbhi => (const) subregion of fine grid to get values -c ::: nvar => (const) number of variables in state vector -c ::: lratio => (const) refinement ratio between levels -c ::: -c ::: crse => (const) coarse grid data widended by 1 zone -c ::: and unrolled -c ::: clo,chi => (const) one dimensional limits of crse grid -c ::: cslo,cshi => (const) coarse grid index limits where -c ::: slopes are to be defined. This is -c ::: the projection of (fblo,fbhi) down -c ::: to the coarse level -c ::: fslo,fshi => (const) fine grid index limits where -c ::: slopes are needed. This is the -c ::: refinement of (cslo,cshi) and -c ::: contains but may not be identical -c ::: to (fblo,fbhi). -c ::: cslope => (modify) temp array coarse grid slopes -c ::: clen => (const) length of coarse gtid slopes -c ::: fslope => (modify) temp array for fine grid slope -c ::: flen => (const) length of fine grid slope array -c ::: fdat => (const) temp array for fine grid data -c ::: cvlo,cvhi => (const) coarse grid index limits where -c ::: volume coordinates are defined -c ::: cvc1 => (const) coarse grid volume coords, x-dir -c ::: cvc2 => (const) coarse grid volume coords, y_dir -c ::: cvc3 => (const) coarse grid volume coords, z-dir -c ::: fvc1 => (const) fine grid volume coords, x-dir -c ::: fvc2 => (const) fine grid volume coords, y-dir -c ::: fvc3 => (const) fine grid volume coords, z-dir -c ::: :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: - -c ::: local var - integer n, fn - integer i, ic, ioff - integer j, jc, joff - integer k, kc, koff - integer ist, jst, kst - REAL_T cen, forw, back, slp - REAL_T xoff, yoff, zoff - REAL_T fcen, ccen - integer ncbx, ncby, ncbz - integer ncsx, ncsy, ncsz - integer islo, jslo, kslo - integer icc, istart, iend - integer lenx, leny, lenz, maxlen - - ncbx = cbhi(1)-cblo(1)+1 - ncby = cbhi(2)-cblo(2)+1 - ncbz = cbhi(3)-cblo(3)+1 - ncsx = ncbx+2 - ncsy = ncby+2 - ncsz = ncbz+2 - ist = 1 - jst = ncsx - kst = ncsx*ncsy - islo = cblo(1)-1 - jslo = cblo(2)-1 - kslo = cblo(3)-1 - lenx = fbhii1-fbloi1+1 - leny = fbhii2-fbloi2+1 - lenz = fbhii3-fbloi3+1 - maxlen = max(lenx,leny,lenz) - if (maxlen .eq. lenx) then - do 380 i = fbloi1, fbhii1 - fn = i-fslo(1)+1 - ic = IX_PROJ(i,lratio) - fcen = half*(fvc1(i)+fvc1(i+1)) - ccen = half*(cvc1(ic)+cvc1(ic+1)) - voff(fn) = (fcen-ccen)/(cvc1(ic+1)-cvc1(ic)) -380 continue - else if (maxlen .eq. leny) then - do 390 j = fbloi2, fbhii2 - fn = j-fslo(2)+1 - jc = IX_PROJ(j,lratio) - fcen = half*(fvc2(j)+fvc2(j+1)) - ccen = half*(cvc2(jc)+cvc2(jc+1)) - voff(fn) = (fcen-ccen)/(cvc2(jc+1)-cvc2(jc)) -390 continue - else - do 400 k = fbloi3, fbhii3 - fn = k-fslo(3)+1 - kc = IX_PROJ(k,lratio) - fcen = half*(fvc3(k)+fvc3(k+1)) - ccen = half*(cvc3(kc)+cvc3(kc+1)) - voff(fn) = (fcen-ccen)/(cvc3(kc+1)-cvc3(kc)) -400 continue - end if - do 410 n = 1, nvar - -c ::: ::::: compute slopes in x direction - do 420 i = 1, clen - cen = half*(crse(i+ist,n)-crse(i-ist,n)) - forw = crse(i+ist,n)-crse(i,n) - back = crse(i,n)-crse(i-ist,n) - slp = sign(one,cen)*min(abs(cen),abs(forw),abs(back)) - cslope(i,1)=merge(slp,zero,forw*back>=0.0d0) -420 continue -c ::: ::::: compute slopes in y direction - do 430 i = 1, clen - cen = half*(crse(i+jst,n)-crse(i-jst,n)) - forw = crse(i+jst,n)-crse(i,n) - back = crse(i,n)-crse(i-jst,n) - slp = sign(one,cen)*min(abs(cen),abs(forw),abs(back)) - cslope(i,2)=merge(slp,zero,forw*back>=0.0d0) -430 continue -c ::: ::::: compute slopes in z direction - do 440 i = 1, clen - cen = half*(crse(i+kst,n)-crse(i-kst,n)) - forw = crse(i+kst,n)-crse(i,n) - back = crse(i,n)-crse(i-kst,n) - slp = sign(one,cen)*min(abs(cen),abs(forw),abs(back)) - cslope(i,3)=merge(slp,zero,forw*back>=0.0d0) -440 continue - - if (maxlen .eq. lenx) then - do 450 kc = cblo(3), cbhi(3) - do 460 jc = cblo(2), cbhi(2) - -c ::: ..,.......::::: strip out a fine grid slope vector - do 470 ioff = 1, lratio - icc = clo + ist + jst*(jc-jslo) + kst*(kc- - $ kslo) - istart = ioff - iend = ioff + (ncbx-1)*lratio - do 480 fn = istart, iend, lratio - fslope(fn,1) = cslope(icc,1) - fslope(fn,2) = cslope(icc,2) - fslope(fn,3) = cslope(icc,3) - fdat(fn) = crse(icc,n) - icc = icc + ist -480 continue -470 continue - - do 490 koff = 0, lratio-1 - k = lratio*kc + koff - if (k .lt. fbloi3) then - goto 490 -c --- next --- - end if - if (k .gt. fbhii3) then - goto 491 -c --- break --- - end if - fcen = half*(fvc3(k)+fvc3(k+1)) - ccen = half*(cvc3(kc)+cvc3(kc+1)) - zoff = (fcen-ccen)/(cvc3(kc+1)-cvc3(kc)) - do 500 joff = 0, lratio-1 - j = lratio*jc + joff - if (j .lt. fbloi2) then - goto 500 -c --- next --- - end if - if (j .gt. fbhii2) then - goto 501 -c --- break --- - end if - fcen = half*(fvc2(j)+fvc2(j+1)) - ccen = half*(cvc2(jc)+cvc2(jc+1)) - yoff = (fcen-ccen)/(cvc2(jc+1)-cvc2(jc)) - - do 510 i = fbloi1, fbhii1 - fn = i-fslo(1)+1 - fine(i,j,k,n) = fdat(fn) + voff(fn)* - $ fslope(fn,1)+yoff*fslope(fn,2)+ zoff* - $ fslope(fn,3) -510 continue -500 continue -501 continue -490 continue -491 continue -460 continue -450 continue - else if (maxlen .eq. leny) then - do 520 kc = cblo(3), cbhi(3) - do 530 ic = cblo(1), cbhi(1) - -c ::: ..,.......::::: strip out a fine grid slope vector - do 540 joff = 1, lratio - icc = clo + ist*(ic-islo) + jst + kst*(kc- - $ kslo) - istart = joff - iend = joff + (ncby-1)*lratio - do 550 fn = istart, iend, lratio - fslope(fn,1) = cslope(icc,1) - fslope(fn,2) = cslope(icc,2) - fslope(fn,3) = cslope(icc,3) - fdat(fn) = crse(icc,n) - icc = icc + jst -550 continue -540 continue - - do 560 koff = 0, lratio-1 - k = lratio*kc + koff - if (k .lt. fbloi3) then - goto 560 -c --- next --- - end if - if (k .gt. fbhii3) then - goto 561 -c --- break --- - end if - fcen = half*(fvc3(k)+fvc3(k+1)) - ccen = half*(cvc3(kc)+cvc3(kc+1)) - zoff = (fcen-ccen)/(cvc3(kc+1)-cvc3(kc)) - do 570 ioff = 0, lratio-1 - i = lratio*ic + ioff - if (i .lt. fbloi1) then - goto 570 -c --- next --- - end if - if (i .gt. fbhii1) then - goto 571 -c --- break --- - end if - fcen = half*(fvc1(i)+fvc1(i+1)) - ccen = half*(cvc1(ic)+cvc1(ic+1)) - xoff = (fcen-ccen)/(cvc1(ic+1)-cvc1(ic)) - - do 580 j = fbloi2, fbhii2 - fn = j-fslo(2)+1 - fine(i,j,k,n) = fdat(fn) + xoff* - $ fslope(fn,1)+voff(fn)*fslope(fn,2)+ - $ zoff*fslope(fn,3) -580 continue -570 continue -571 continue -560 continue -561 continue -530 continue -520 continue - else - do 590 jc = cblo(2), cbhi(2) - do 600 ic = cblo(1), cbhi(1) - -c ::: ..,.......::::: strip out a fine grid slope vector - do 610 koff = 1, lratio - icc = clo + ist*(ic-islo) + jst*(jc-jslo) + - $ kst - istart = koff - iend = koff + (ncbz-1)*lratio - do 620 fn = istart, iend, lratio - fslope(fn,1) = cslope(icc,1) - fslope(fn,2) = cslope(icc,2) - fslope(fn,3) = cslope(icc,3) - fdat(fn) = crse(icc,n) - icc = icc + kst -620 continue -610 continue - - do 630 joff = 0, lratio-1 - j = lratio*jc + joff - if (j .lt. fbloi2) then - goto 630 -c --- next --- - end if - if (j .gt. fbhii2) then - goto 631 -c --- break --- - end if - fcen = half*(fvc2(j)+fvc2(j+1)) - ccen = half*(cvc2(jc)+cvc2(jc+1)) - yoff = (fcen-ccen)/(cvc2(jc+1)-cvc2(jc)) - do 640 ioff = 0, lratio-1 - i = lratio*ic + ioff - if (i .lt. fbloi1) then - goto 640 -c --- next --- - end if - if (i .gt. fbhii1) then - goto 641 -c --- break --- - end if - fcen = half*(fvc1(i)+fvc1(i+1)) - ccen = half*(cvc1(ic)+cvc1(ic+1)) - xoff = (fcen-ccen)/(cvc1(ic+1)-cvc1(ic)) - - do 650 k = fbloi3, fbhii3 - fn = k-fslo(3)+1 - fine(i,j,k,n) = fdat(fn) + xoff* - $ fslope(fn,1)+yoff*fslope(fn,2)+ - $ voff(fn)*fslope(fn,3) -650 continue -640 continue -641 continue -630 continue -631 continue -600 continue -590 continue - end if -410 continue - - return - end - - diff --git a/Src/Extern/amrdata/CMakeLists.txt b/Src/Extern/amrdata/CMakeLists.txt index 10761f6a641..d17fcddec19 100644 --- a/Src/Extern/amrdata/CMakeLists.txt +++ b/Src/Extern/amrdata/CMakeLists.txt @@ -12,7 +12,6 @@ foreach(D IN LISTS AMReX_SPACEDIM) AMReX_WritePlotFile.H AMReX_WritePlotFile.cpp AMReX_AmrvisConstants.H - AMReX_FABUTIL_${D}D.F ) if (AMReX_PROFPARSER) diff --git a/Src/Extern/amrdata/Make.package b/Src/Extern/amrdata/Make.package index 3f3769ad174..9368e0669b3 100644 --- a/Src/Extern/amrdata/Make.package +++ b/Src/Extern/amrdata/Make.package @@ -1,6 +1,5 @@ CEXE_sources += AMReX_AmrData.cpp AMReX_XYPlotDataList.cpp AMReX_DataServices.cpp AMReX_WritePlotFile.cpp CEXE_headers += AMReX_AmrData.H AMReX_AmrvisConstants.H AMReX_XYPlotDataList.H AMReX_DataServices.H AMReX_WritePlotFile.H -FEXE_sources += AMReX_FABUTIL_${DIM}D.F VPATH_LOCATIONS += $(AMREX_HOME)/Src/Extern/amrdata INCLUDE_LOCATIONS += $(AMREX_HOME)/Src/Extern/amrdata diff --git a/Tools/CMake/AMReXOptions.cmake b/Tools/CMake/AMReXOptions.cmake index c99c3a63791..a59456d7bb8 100644 --- a/Tools/CMake/AMReXOptions.cmake +++ b/Tools/CMake/AMReXOptions.cmake @@ -284,8 +284,7 @@ print_option(AMReX_FORTRAN_INTERFACES) option( AMReX_LINEAR_SOLVERS "Build AMReX Linear solvers" ON ) print_option( AMReX_LINEAR_SOLVERS ) -cmake_dependent_option( AMReX_AMRDATA "Build data services" OFF - "AMReX_FORTRAN" OFF ) +option( AMReX_AMRDATA "Build data services" OFF ) print_option( AMReX_AMRDATA ) option( AMReX_PARTICLES "Build particle classes" ON) From fd1633e4be1146206ebcee6aed03933135ea960a Mon Sep 17 00:00:00 2001 From: Weiqun Zhang Date: Fri, 26 Jul 2024 09:56:45 -0700 Subject: [PATCH 2/5] ParmParse: Math expression support (#4032) ParmParse: Math expression support Support math expression for integers and floating point numbers in ParmParse. For example, n_cell = 128 amrex.n_cell = n_cell*2 8 16**2 becomes n_cell = 128 amrex.n_cell = 256 8 256 Note that if the expression contains another variable, it will be looked up by ParmParse. ParmParse's constructor now accepts an optional second argument, `parser_prefix`. When a variable in a math expression is being looked up, it will first try to find it by using the exact name of the variable. If this attempt fails and the `ParmParse` object has a non-empty `parser_prefix`, it will try again, this time looking up the variable by prefixing its name with `parser_prefix` followed by a `.`. For example, physical_constants.c = 3.e8 amrex.pi = 3.14 amrex.foo = sin(amrex.pi/2)*c**2 will give `foo = 8.999997146e+16` if we do amrex::ParmParse pp("amrex", "physical_constants"); double foo; pp.get("foo", foo); --- Docs/sphinx_documentation/source/Basics.rst | 159 +++++++++- Src/Base/AMReX_ParmParse.H | 90 +++++- Src/Base/AMReX_ParmParse.cpp | 315 +++++++++++++++----- 3 files changed, 479 insertions(+), 85 deletions(-) diff --git a/Docs/sphinx_documentation/source/Basics.rst b/Docs/sphinx_documentation/source/Basics.rst index 5887df56fb5..1502def6a88 100644 --- a/Docs/sphinx_documentation/source/Basics.rst +++ b/Docs/sphinx_documentation/source/Basics.rst @@ -224,17 +224,17 @@ file is a series of definitions in the form of ``prefix.name = value value ....`` For each line, text after # are comments. Here is an example inputs file. - .. highlight:: python +.. highlight:: python - :: +:: - nsteps = 100 # integer - nsteps = 1000 # nsteps appears a second time - dt = 0.03 # floating point number - ncells = 128 64 32 # a list of 3 ints - xrange = -0.5 0.5 # a list of 2 reals - title = "Three Kingdoms" # a string - hydro.cfl = 0.8 # with prefix, hydro + nsteps = 100 # integer + nsteps = 1000 # nsteps appears a second time + dt = 0.03 # floating point number + ncells = 128 64 32 # a list of 3 ints + xrange = -0.5 0.5 # a list of 2 reals + title = "Three Kingdoms" # a string + hydro.cfl = 0.8 # with prefix, hydro The following code shows how to use :cpp:`ParmParse` to get/query the values. @@ -275,6 +275,147 @@ by default returns the last one. The difference between :cpp:`query` and get the value, whereas :cpp:`query` returns an error code without generating a runtime error that will abort the run. +Math Expressions +---------------- + +:cpp:`ParmParse` supports math expressions for integers and floating point +numbers. For example, + +.. highlight:: python + +:: + + # three numbers. whitespaces inside `""` are okay. + f = 3+4 99 "5 + 6" + + # two numbers. `\` is for continuation + g = 3.1+4.1 \ + 5.0+6.6 + + # two numbers unless using [query|get]WithParser + w = 1 -2 + + my_constants.alpha = 5. + amrex.c = c + + # must use [query|get]WithParser + amrex.foo = sin( pi/2 ) + alpha + -amrex.c**2/c^2 + + # either [query|get] or [query|get]WithParser is okay + amrex.bar = sin(pi/2)+alpha+-amrex.c**2/c^2 + + geom.prob_lo = 2*sin(pi/4)/sqrt(2) sin(pi/2)+cos(pi/2) -(sin(pi*3/2)+cos(pi*3/2)) + + # three numbers. `\` is for continuation + geom.prob_hi = "2*sin(pi/4)/sqrt(2)" \ + "sin(pi/2) + cos(pi/2)" \ + -(sin(pi*3/2)+cos(pi*3/2)) + +can be processed by + +.. highlight:: c++ + +:: + + { + ParmParse::SetParserPrefix("physical_constants"); + ParmParse pp("physical_constants"); + pp.add("c", 299792458.); + pp.add("pi", 3.14159265358979323846); + } + { + ParmParse pp; + + double f0 = -1; + pp.query("f", f0); + std::cout << " double f = " << f0 << '\n'; + + std::vector f; + pp.queryarr("f", f); + std::cout << " int f[3] = {" << f[0] << ", " << f[1] << ", " + << f[2] << "}\n"; + + std::vector g; + pp.queryarr("g", g); + std::cout << " double g[] = " << g[0] << " " << g[1] << '\n'; + + double w; + pp.query("w", w); + std::cout << " w = " << w << " with query\n"; + pp.queryWithParser("w", w); + std::cout << " w = " << w << " with queryParser\n"; + } + { + ParmParse pp("amrex", "my_constants"); + double foo = -1, bar; + pp.getWithParser("foo", foo); + pp.get("bar", bar); + std::cout << " foo = " << foo << ", bar = " << bar << '\n'; + } + { + ParmParse pp; + std::array prob_lo, prob_hi; + pp.get("geom.prob_lo", prob_lo); + pp.get("geom.prob_hi", prob_hi); + std::cout << " double prob_lo[] = {" << prob_lo[0] << ", " + << prob_lo[1] << ", " << prob_lo[2] << "}\n" + << " double prob_hi[] = {" << prob_hi[0] << ", " + << prob_hi[1] << ", " << prob_hi[2] << "}\n"; + } + +The results will be + +.. highlight:: console + +:: + + double f = 7 + int f[3] = {7, 99, 11} + double g[] = 7.2 11.6 + w = 1 with query + w = -1 with queryParser + foo = 5, bar = 5 + double prob_lo[] = {1, 1, 1} + double prob_hi[] = {1, 1, 1} + +Note that the empty spaces are significant for math expressions unless they +are inside a pair of ``"`` or explicitly parsed by +:cpp:`ParmParse::queryWithParser` or :cpp:`ParmParse::getWithParser`. If the +expression contains another variable, it will be looked up by +:cpp:`ParmParse`. :cpp:`ParmParse`'s constructor accepts an optional second +argument, ``parser_prefix``. When a variable in a math expression is being +looked up, it will first try to find it by using the exact name of the +variable. If this attempt fails and the :cpp:`ParmParse` object has a +non-empty non-static member ``parser_prefix``, it will try again, this time +looking up the variable by prefixing its name with the value of +``parser_prefix`` followed by a ``.``. If this attempt also fails and the +:cpp:`ParmParse` class has a non-empty static member ``ParserPrefix`` (which +can be set by :cpp:`ParmParse::SetParserPrefix`), it will try again, this +time looking up the variable by prefixing its name with the value of +``ParserPrefix`` followed by a ``.``. + +The variables in :cpp:`ParmParse` math expressions are not evaluated until +they are referenced. If a variable is defined multiple times, the last +occurrence will override previous ones even if it appears after the variable +has been referenced. This behavior is demonstrated in the following example. + +.. highlight:: python + +:: + + foo.a = 1 + foo.b = foo.a + foo.a = 2 + +will become + +.. highlight:: python + +:: + + foo.a = 2 + foo.b = 2 + Overriding Parameters with Command-Line Arguments ------------------------------------------------- diff --git a/Src/Base/AMReX_ParmParse.H b/Src/Base/AMReX_ParmParse.H index 844c83aef32..27d93eb67a2 100644 --- a/Src/Base/AMReX_ParmParse.H +++ b/Src/Base/AMReX_ParmParse.H @@ -4,6 +4,8 @@ #include #include +#include +#include #include #include @@ -268,6 +270,17 @@ using IntVect = IntVectND; * t = 1.5 * #endif * +* Math expression is supported for integers and reals. For example +* +* n_cell = 128 +* amrex.n_cell = n_cell*2 8 16**2 +* +* becomes +* +* n_cell = 128 +* amrex.n_cell = 256 8 256 +* +* More details can be found at https://amrex-codes.github.io/amrex/docs_html/Basics.html#parmparse */ class ParmParse { @@ -275,11 +288,13 @@ public: enum { LAST = -1, FIRST = 0, ALL = -1 }; /** * \brief Construct an additional ParmParse object sharing the same - * internal table as any other such objects in existence. If - * prefix is specified, load this string as the code prefix - * for this particular ParmParse object. + * internal table as any other such objects in existence. If prefix is + * specified, load this string as the code prefix for this particular + * ParmParse object. If parser_prefix is specified, it will be used as + * prefixed in math expression evaluations. */ - explicit ParmParse (std::string prefix = std::string()); + explicit ParmParse (std::string prefix = std::string(), + std::string parser_prefix = std::string()); //! Returns true if name is in table. [[nodiscard]] bool contains (const char* name) const; @@ -997,9 +1012,70 @@ public: return exist; } + /** + * \brief Query with Parser. If `name` is found, this uses amrex::Parser + * to parse the entire list of empty space separated values as a single + * scalar. The return value indicates whether it's found. + */ + int queryWithParser (const char* name, int& ref) const; + int queryWithParser (const char* name, long& ref) const; + int queryWithParser (const char* name, long long& ref) const; + int queryWithParser (const char* name, float& ref) const; + int queryWithParser (const char* name, double& ref) const; + + /** + * \brief Query with Parser. If `name` is found, this uses amrex::Parser + * to parse the entire list of empty space separated values as a single + * scalar. If not, the value in `ref` will be added to the ParmParse + * database. The return value indicates whether it's found. + */ + template || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v,int> = 0> + int queryAddWithParser (const char* name, T& ref) const + { + int exist = this->queryWithParser(name, ref); + if (!exist) { + this->add(name, ref); + } + return exist; + } + + /** + * \brief Get with Parser. If `name` is found, this uses amrex::Parser + * to parse the entire list of empty space separated values as a single + * scalar. If not, it's a runtime error. + */ + template || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v,int> = 0> + void getWithParser (const char* name, T& ref) const + { + int exist = this->queryWithParser(name, ref); + if (!exist) { + amrex::Error(std::string("ParmParse::getWithParser: failed to get ")+name); + } + } + //! Remove given name from the table. int remove (const char* name); + //! Make Parser using given string `func` as function body and `vars` as + //! variable names. Constants known to ParmParse will be set. It's a + //! runtime error, if there are unknown symbols in `func`. + [[nodiscard]] Parser makeParser (std::string const& func, + Vector const& vars) const; + + //! Make IParser using given string `func` as function body and `vars` + //! as variable names. Constants known to ParmParse will be set. It's a + //! runtime error, if there are unknown symbols in `func`. + [[nodiscard]] IParser makeIParser (std::string const& func, + Vector const& vars) const; + /** * \brief Construct an initial ParmParse object from the argc and argv * passed in to main(). An error will be signalled if another @@ -1014,6 +1090,9 @@ public: */ static void Finalize (); + //! Set prefix used by math expression Parser + static void SetParserPrefix (std::string a_prefix); + static int Verbose (); static void SetVerbose (int v); @@ -1049,11 +1128,14 @@ public: //! keyword for files to load static std::string const FileKeyword; + static std::string ParserPrefix; + protected: [[nodiscard]] std::string prefixedName (const std::string_view& str) const; std::string m_prefix; // Prefix used in keyword search + std::string m_parser_prefix; // Prefix used by Parser Table* m_table; }; diff --git a/Src/Base/AMReX_ParmParse.cpp b/Src/Base/AMReX_ParmParse.cpp index c24f60a46f9..f78da0e5e7e 100644 --- a/Src/Base/AMReX_ParmParse.cpp +++ b/Src/Base/AMReX_ParmParse.cpp @@ -14,6 +14,7 @@ #include #include #include +#include extern "C" void amrex_init_namelist (const char*); extern "C" void amrex_finalize_namelist (); @@ -23,15 +24,18 @@ namespace amrex { namespace { bool initialized = false; ParmParse::Table g_table; + std::vector> g_parser_recursive_symbols; namespace pp_detail { int verbose = -1; } } std::string const ParmParse::FileKeyword = "FILE"; +std::string ParmParse::ParserPrefix; -ParmParse::ParmParse (std::string prefix) +ParmParse::ParmParse (std::string prefix, std::string parser_prefix) : m_prefix(std::move(prefix)), + m_parser_prefix(std::move(parser_prefix)), m_table(&g_table) {} @@ -65,8 +69,8 @@ std::string pp_to_string (std::string const& name, enum PType { pDefn, - pValue, pEQ_sign, + pValue, pEOF }; @@ -616,9 +620,14 @@ bldTable (const char*& str, ParmParse::Table& tab) } } +template +bool pp_parser (const ParmParse::Table& table, const std::string& parser_prefix, + const std::string& name, const std::string& val, T& ref); + template bool squeryval (const ParmParse::Table& table, + const std::string& parser_prefix, const std::string& name, T& ref, int ival, @@ -656,6 +665,16 @@ squeryval (const ParmParse::Table& table, bool ok = is(valname, ref); if ( !ok ) { + if constexpr (std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v) { + if (pp_parser(table, parser_prefix, name, valname, ref)) { + return true; + } + } + amrex::ErrorStream() << "ParmParse::queryval type mismatch on value number " << ival << " of " << '\n'; if ( occurrence == ParmParse::LAST ) @@ -680,12 +699,13 @@ squeryval (const ParmParse::Table& table, template void sgetval (const ParmParse::Table& table, + const std::string& parser_prefix, const std::string& name, T& ref, int ival, int occurrence) { - if ( squeryval(table, name,ref,ival,occurrence) == 0 ) + if ( squeryval(table, parser_prefix, name,ref,ival,occurrence) == 0 ) { amrex::ErrorStream() << "ParmParse::getval "; if ( occurrence >= 0 ) @@ -707,6 +727,7 @@ sgetval (const ParmParse::Table& table, template bool squeryarr (const ParmParse::Table& table, + const std::string& parser_prefix, const std::string& name, std::vector& ref, int start_ix, @@ -757,6 +778,16 @@ squeryarr (const ParmParse::Table& table, bool ok = is(valname, ref[n]); if ( !ok ) { + if constexpr (std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v || + std::is_same_v) { + if (pp_parser(table, parser_prefix, name, valname, ref[n])) { + continue; + } + } + amrex::ErrorStream() << "ParmParse::queryarr type mismatch on value number " << n << " of "; if ( occurrence == ParmParse::LAST ) @@ -782,13 +813,14 @@ squeryarr (const ParmParse::Table& table, template void sgetarr (const ParmParse::Table& table, + const std::string& parser_prefix, const std::string& name, std::vector& ref, int start_ix, int num_val, int occurrence) { - if ( squeryarr(table,name,ref,start_ix,num_val,occurrence) == 0 ) + if ( squeryarr(table,parser_prefix,name,ref,start_ix,num_val,occurrence) == 0 ) { amrex::ErrorStream() << "ParmParse::sgetarr "; if ( occurrence >= 0 ) @@ -903,6 +935,71 @@ void pp_print_unused (const std::string& pfx, const ParmParse::Table& table) } } +template , + IParser, Parser>> +PARSER_t +pp_make_parser (std::string const& func, Vector const& vars, + ParmParse::Table const& table, std::string const& parser_prefix) +{ + using value_t = std::conditional_t, int, double>; + + std::vector prefixes; + prefixes.reserve(3); + prefixes.emplace_back(); + if (! parser_prefix.empty()) { + prefixes.emplace_back(parser_prefix+"."); + } + if (! ParmParse::ParserPrefix.empty()) { + prefixes.emplace_back(ParmParse::ParserPrefix+"."); + } + + PARSER_t parser(func); + + auto symbols = parser.symbols(); + for (auto const& var : vars) { + symbols.erase(var); + } + + for (auto const& s : symbols) { + value_t v = 0; + bool r = false; + for (auto const& pf : prefixes) { + r = squeryval(table, parser_prefix, pf+s, v, + ParmParse::FIRST, ParmParse::LAST); + if (r) { break; } + } + if (r == false) { + amrex::Error("ParmParse: failed to parse " + func); + } + parser.setConstant(s, v); + } + if (!vars.empty()) { + parser.registerVariables(vars); + } + + return parser; +} + +template +bool pp_parser (const ParmParse::Table& table, const std::string& parser_prefix, + const std::string& name, const std::string& val, T& ref) +{ + auto& recursive_symbols = g_parser_recursive_symbols[OpenMP::get_thread_num()]; + if (auto found = recursive_symbols.find(name); found != recursive_symbols.end()) { + amrex::Error("ParmParse: recursive reference to "+name+" is not allowed"); + return false; + } else { + recursive_symbols.insert(name); + } + + auto parser = pp_make_parser(val, {}, table, parser_prefix); + auto exe = parser.template compileHost<0>(); + ref = static_cast(exe()); + + recursive_symbols.erase(name); + return true; +} + } // End of unnamed namespace. std::string @@ -943,6 +1040,8 @@ ParmParse::Initialize (int argc, amrex::Error("ParmParse::Initialize(): already initialized!"); } + g_parser_recursive_symbols.resize(OpenMP::get_max_threads()); + ppinit(argc, argv, parfile, g_table); amrex::ExecOnFinalize(ParmParse::Finalize); @@ -1050,10 +1149,18 @@ ParmParse::Finalize () amrex_finalize_namelist(); #endif + g_parser_recursive_symbols.clear(); + pp_detail::verbose = -1; initialized = false; } +void +ParmParse::SetParserPrefix (std::string a_prefix) +{ + ParmParse::ParserPrefix = std::move(a_prefix); +} + void ParmParse::dumpTable (std::ostream& os, bool prettyPrint) { @@ -1097,7 +1204,7 @@ ParmParse::getkth (const char* name, bool& ref, int ival) const { - sgetval(*m_table, prefixedName(name),ref,ival,k); + sgetval(*m_table,m_parser_prefix, prefixedName(name),ref,ival,k); } void @@ -1105,7 +1212,7 @@ ParmParse::get (const char* name, bool& ref, int ival) const { - sgetval(*m_table, prefixedName(name),ref,ival, LAST); + sgetval(*m_table,m_parser_prefix, prefixedName(name),ref,ival, LAST); } int @@ -1114,7 +1221,7 @@ ParmParse::querykth (const char* name, bool& ref, int ival) const { - return squeryval(*m_table, prefixedName(name),ref,ival,k); + return squeryval(*m_table,m_parser_prefix, prefixedName(name),ref,ival,k); } int @@ -1122,7 +1229,7 @@ ParmParse::query (const char* name, bool& ref, int ival) const { - return squeryval(*m_table, prefixedName(name),ref,ival, LAST); + return squeryval(*m_table,m_parser_prefix, prefixedName(name),ref,ival, LAST); } void @@ -1136,25 +1243,25 @@ ParmParse::add (const char* name, void ParmParse::getkth (const char* name, int k, int& ref, int ival) const { - sgetval(*m_table, prefixedName(name),ref,ival,k); + sgetval(*m_table,m_parser_prefix, prefixedName(name),ref,ival,k); } void ParmParse::get (const char* name, int& ref, int ival) const { - sgetval(*m_table, prefixedName(name),ref,ival, LAST); + sgetval(*m_table,m_parser_prefix, prefixedName(name),ref,ival, LAST); } int ParmParse::querykth (const char* name, int k, int& ref, int ival) const { - return squeryval(*m_table, prefixedName(name),ref,ival,k); + return squeryval(*m_table,m_parser_prefix, prefixedName(name),ref,ival,k); } int ParmParse::query (const char* name, int& ref, int ival) const { - return squeryval(*m_table, prefixedName(name),ref,ival, LAST); + return squeryval(*m_table,m_parser_prefix, prefixedName(name),ref,ival, LAST); } void @@ -1167,28 +1274,28 @@ void ParmParse::getktharr (const char* name, int k, std::vector& ref, int start_ix, int num_val) const { - sgetarr(*m_table, prefixedName(name),ref,start_ix,num_val,k); + sgetarr(*m_table,m_parser_prefix, prefixedName(name),ref,start_ix,num_val,k); } void ParmParse::getarr (const char* name, std::vector& ref, int start_ix, int num_val) const { - sgetarr(*m_table, prefixedName(name),ref,start_ix,num_val, LAST); + sgetarr(*m_table,m_parser_prefix, prefixedName(name),ref,start_ix,num_val, LAST); } int ParmParse::queryktharr (const char* name, int k, std::vector& ref, int start_ix, int num_val) const { - return squeryarr(*m_table, prefixedName(name),ref,start_ix,num_val,k); + return squeryarr(*m_table,m_parser_prefix, prefixedName(name),ref,start_ix,num_val,k); } int ParmParse::queryarr (const char* name, std::vector& ref, int start_ix, int num_val) const { - return squeryarr(*m_table, prefixedName(name),ref,start_ix,num_val, LAST); + return squeryarr(*m_table,m_parser_prefix, prefixedName(name),ref,start_ix,num_val, LAST); } void @@ -1202,25 +1309,25 @@ ParmParse::addarr (const char* name, const std::vector& ref) void ParmParse::getkth (const char* name, int k, long& ref, int ival) const { - sgetval(*m_table, prefixedName(name),ref,ival,k); + sgetval(*m_table,m_parser_prefix, prefixedName(name),ref,ival,k); } void ParmParse::get (const char* name, long& ref, int ival) const { - sgetval(*m_table, prefixedName(name),ref,ival, LAST); + sgetval(*m_table,m_parser_prefix, prefixedName(name),ref,ival, LAST); } int ParmParse::querykth (const char* name, int k, long& ref, int ival) const { - return squeryval(*m_table, prefixedName(name),ref,ival,k); + return squeryval(*m_table,m_parser_prefix, prefixedName(name),ref,ival,k); } int ParmParse::query (const char* name, long& ref, int ival) const { - return squeryval(*m_table, prefixedName(name),ref,ival, LAST); + return squeryval(*m_table,m_parser_prefix, prefixedName(name),ref,ival, LAST); } void @@ -1234,28 +1341,28 @@ void ParmParse::getktharr (const char* name, int k, std::vector& ref, int start_ix, int num_val) const { - sgetarr(*m_table, prefixedName(name),ref,start_ix,num_val,k); + sgetarr(*m_table,m_parser_prefix, prefixedName(name),ref,start_ix,num_val,k); } void ParmParse::getarr (const char* name, std::vector& ref, int start_ix, int num_val) const { - sgetarr(*m_table, prefixedName(name),ref,start_ix,num_val, LAST); + sgetarr(*m_table,m_parser_prefix, prefixedName(name),ref,start_ix,num_val, LAST); } int ParmParse::queryktharr (const char* name, int k, std::vector& ref, int start_ix, int num_val) const { - return squeryarr(*m_table, prefixedName(name),ref,start_ix,num_val,k); + return squeryarr(*m_table,m_parser_prefix, prefixedName(name),ref,start_ix,num_val,k); } int ParmParse::queryarr (const char* name, std::vector& ref, int start_ix, int num_val) const { - return squeryarr(*m_table, prefixedName(name),ref,start_ix,num_val, LAST); + return squeryarr(*m_table,m_parser_prefix, prefixedName(name),ref,start_ix,num_val, LAST); } void @@ -1268,25 +1375,25 @@ ParmParse::addarr (const char* name, const std::vector& ref) void ParmParse::getkth (const char* name, int k, long long& ref, int ival) const { - sgetval(*m_table, prefixedName(name),ref,ival,k); + sgetval(*m_table,m_parser_prefix, prefixedName(name),ref,ival,k); } void ParmParse::get (const char* name, long long& ref, int ival) const { - sgetval(*m_table, prefixedName(name),ref,ival, LAST); + sgetval(*m_table,m_parser_prefix, prefixedName(name),ref,ival, LAST); } int ParmParse::querykth (const char* name, int k, long long& ref, int ival) const { - return squeryval(*m_table, prefixedName(name),ref,ival,k); + return squeryval(*m_table,m_parser_prefix, prefixedName(name),ref,ival,k); } int ParmParse::query (const char* name, long long& ref, int ival) const { - return squeryval(*m_table, prefixedName(name),ref,ival, LAST); + return squeryval(*m_table,m_parser_prefix, prefixedName(name),ref,ival, LAST); } void @@ -1299,28 +1406,28 @@ void ParmParse::getktharr (const char* name, int k, std::vector& ref, int start_ix, int num_val) const { - sgetarr(*m_table, prefixedName(name),ref,start_ix,num_val,k); + sgetarr(*m_table,m_parser_prefix, prefixedName(name),ref,start_ix,num_val,k); } void ParmParse::getarr (const char* name, std::vector& ref, int start_ix, int num_val) const { - sgetarr(*m_table, prefixedName(name),ref,start_ix,num_val, LAST); + sgetarr(*m_table,m_parser_prefix, prefixedName(name),ref,start_ix,num_val, LAST); } int ParmParse::queryktharr (const char* name, int k, std::vector& ref, int start_ix, int num_val) const { - return squeryarr(*m_table, prefixedName(name),ref,start_ix,num_val,k); + return squeryarr(*m_table,m_parser_prefix, prefixedName(name),ref,start_ix,num_val,k); } int ParmParse::queryarr (const char* name, std::vector& ref, int start_ix, int num_val) const { - return squeryarr(*m_table, prefixedName(name),ref,start_ix,num_val, LAST); + return squeryarr(*m_table,m_parser_prefix, prefixedName(name),ref,start_ix,num_val, LAST); } void @@ -1333,25 +1440,25 @@ ParmParse::addarr (const char* name, const std::vector& ref) void ParmParse::getkth (const char* name, int k, float& ref, int ival) const { - sgetval(*m_table, prefixedName(name),ref,ival,k); + sgetval(*m_table,m_parser_prefix, prefixedName(name),ref,ival,k); } void ParmParse::get (const char* name, float& ref, int ival) const { - sgetval(*m_table, prefixedName(name),ref,ival, LAST); + sgetval(*m_table,m_parser_prefix, prefixedName(name),ref,ival, LAST); } int ParmParse::querykth (const char* name, int k, float& ref, int ival) const { - return squeryval(*m_table, prefixedName(name),ref,ival,k); + return squeryval(*m_table,m_parser_prefix, prefixedName(name),ref,ival,k); } int ParmParse::query (const char* name, float& ref, int ival) const { - return squeryval(*m_table, prefixedName(name),ref,ival, LAST); + return squeryval(*m_table,m_parser_prefix, prefixedName(name),ref,ival, LAST); } void @@ -1364,28 +1471,28 @@ void ParmParse::getktharr (const char* name, int k, std::vector& ref, int start_ix, int num_val) const { - sgetarr(*m_table, prefixedName(name),ref,start_ix,num_val,k); + sgetarr(*m_table,m_parser_prefix, prefixedName(name),ref,start_ix,num_val,k); } void ParmParse::getarr (const char* name, std::vector& ref, int start_ix, int num_val) const { - sgetarr(*m_table, prefixedName(name),ref,start_ix,num_val, LAST); + sgetarr(*m_table,m_parser_prefix, prefixedName(name),ref,start_ix,num_val, LAST); } int ParmParse::queryktharr (const char* name, int k, std::vector& ref, int start_ix, int num_val) const { - return squeryarr(*m_table, prefixedName(name),ref,start_ix, num_val,k); + return squeryarr(*m_table,m_parser_prefix, prefixedName(name),ref,start_ix, num_val,k); } int ParmParse::queryarr (const char* name, std::vector& ref, int start_ix, int num_val) const { - return squeryarr(*m_table, prefixedName(name),ref,start_ix,num_val, LAST); + return squeryarr(*m_table,m_parser_prefix, prefixedName(name),ref,start_ix,num_val, LAST); } void @@ -1400,25 +1507,25 @@ ParmParse::addarr (const char* name, const std::vector& ref) void ParmParse::getkth (const char* name, int k, double& ref, int ival) const { - sgetval(*m_table, prefixedName(name),ref,ival,k); + sgetval(*m_table,m_parser_prefix, prefixedName(name),ref,ival,k); } void ParmParse::get (const char* name, double& ref, int ival) const { - sgetval(*m_table, prefixedName(name),ref,ival, LAST); + sgetval(*m_table,m_parser_prefix, prefixedName(name),ref,ival, LAST); } int ParmParse::querykth (const char* name, int k, double& ref, int ival) const { - return squeryval(*m_table, prefixedName(name),ref,ival,k); + return squeryval(*m_table,m_parser_prefix, prefixedName(name),ref,ival,k); } int ParmParse::query (const char* name, double& ref, int ival) const { - return squeryval(*m_table, prefixedName(name),ref,ival, LAST); + return squeryval(*m_table,m_parser_prefix, prefixedName(name),ref,ival, LAST); } void @@ -1431,28 +1538,28 @@ void ParmParse::getktharr (const char* name, int k, std::vector& ref, int start_ix, int num_val) const { - sgetarr(*m_table, prefixedName(name),ref,start_ix,num_val,k); + sgetarr(*m_table,m_parser_prefix, prefixedName(name),ref,start_ix,num_val,k); } void ParmParse::getarr (const char* name, std::vector& ref, int start_ix, int num_val) const { - sgetarr(*m_table, prefixedName(name),ref,start_ix,num_val, LAST); + sgetarr(*m_table,m_parser_prefix, prefixedName(name),ref,start_ix,num_val, LAST); } int ParmParse::queryktharr (const char* name, int k, std::vector& ref, int start_ix, int num_val) const { - return squeryarr(*m_table, prefixedName(name),ref,start_ix, num_val,k); + return squeryarr(*m_table,m_parser_prefix, prefixedName(name),ref,start_ix, num_val,k); } int ParmParse::queryarr (const char* name, std::vector& ref, int start_ix, int num_val) const { - return squeryarr(*m_table, prefixedName(name),ref,start_ix,num_val, LAST); + return squeryarr(*m_table,m_parser_prefix, prefixedName(name),ref,start_ix,num_val, LAST); } void @@ -1467,25 +1574,25 @@ ParmParse::addarr (const char* name, const std::vector& ref) void ParmParse::getkth (const char* name, int k, std::string& ref, int ival) const { - sgetval(*m_table, prefixedName(name),ref,ival,k); + sgetval(*m_table,m_parser_prefix, prefixedName(name),ref,ival,k); } void ParmParse::get (const char* name, std::string& ref, int ival) const { - sgetval(*m_table, prefixedName(name),ref,ival, LAST); + sgetval(*m_table,m_parser_prefix, prefixedName(name),ref,ival, LAST); } int ParmParse::querykth (const char* name, int k, std::string& ref, int ival) const { - return squeryval(*m_table, prefixedName(name),ref,ival,k); + return squeryval(*m_table,m_parser_prefix, prefixedName(name),ref,ival,k); } int ParmParse::query (const char* name, std::string& ref, int ival) const { - return squeryval(*m_table, prefixedName(name),ref,ival, LAST); + return squeryval(*m_table,m_parser_prefix, prefixedName(name),ref,ival, LAST); } void @@ -1498,28 +1605,28 @@ void ParmParse::getktharr (const char* name, int k, std::vector& ref, int start_ix, int num_val) const { - sgetarr(*m_table, prefixedName(name),ref,start_ix,num_val,k); + sgetarr(*m_table,m_parser_prefix, prefixedName(name),ref,start_ix,num_val,k); } void ParmParse::getarr (const char* name, std::vector& ref, int start_ix, int num_val) const { - sgetarr(*m_table, prefixedName(name),ref,start_ix,num_val, LAST); + sgetarr(*m_table,m_parser_prefix, prefixedName(name),ref,start_ix,num_val, LAST); } int ParmParse::queryktharr (const char* name, int k, std::vector& ref, int start_ix, int num_val) const { - return squeryarr(*m_table, prefixedName(name),ref,start_ix, num_val,k); + return squeryarr(*m_table,m_parser_prefix, prefixedName(name),ref,start_ix, num_val,k); } int ParmParse::queryarr (const char* name, std::vector& ref, int start_ix, int num_val) const { - return squeryarr(*m_table, prefixedName(name),ref,start_ix,num_val, LAST); + return squeryarr(*m_table,m_parser_prefix, prefixedName(name),ref,start_ix,num_val, LAST); } void @@ -1534,25 +1641,25 @@ ParmParse::addarr (const char* name, const std::vector& ref) void ParmParse::getkth (const char* name, int k, IntVect& ref, int ival) const { - sgetval(*m_table, prefixedName(name),ref,ival,k); + sgetval(*m_table,m_parser_prefix, prefixedName(name),ref,ival,k); } void ParmParse::get (const char* name, IntVect& ref, int ival) const { - sgetval(*m_table, prefixedName(name),ref,ival, LAST); + sgetval(*m_table,m_parser_prefix, prefixedName(name),ref,ival, LAST); } int ParmParse::querykth (const char* name, int k, IntVect& ref, int ival) const { - return squeryval(*m_table, prefixedName(name),ref,ival,k); + return squeryval(*m_table,m_parser_prefix, prefixedName(name),ref,ival,k); } int ParmParse::query (const char* name, IntVect& ref, int ival) const { - return squeryval(*m_table, prefixedName(name),ref,ival, LAST); + return squeryval(*m_table,m_parser_prefix, prefixedName(name),ref,ival, LAST); } void @@ -1565,28 +1672,28 @@ void ParmParse::getktharr (const char* name, int k, std::vector& ref, int start_ix, int num_val) const { - sgetarr(*m_table, prefixedName(name),ref,start_ix,num_val,k); + sgetarr(*m_table,m_parser_prefix, prefixedName(name),ref,start_ix,num_val,k); } void ParmParse::getarr (const char* name, std::vector& ref, int start_ix, int num_val) const { - sgetarr(*m_table, prefixedName(name),ref,start_ix,num_val, LAST); + sgetarr(*m_table,m_parser_prefix, prefixedName(name),ref,start_ix,num_val, LAST); } int ParmParse::queryktharr (const char* name, int k, std::vector& ref, int start_ix, int num_val) const { - return squeryarr(*m_table, prefixedName(name),ref,start_ix, num_val,k); + return squeryarr(*m_table,m_parser_prefix, prefixedName(name),ref,start_ix, num_val,k); } int ParmParse::queryarr (const char* name, std::vector& ref, int start_ix, int num_val) const { - return squeryarr(*m_table, prefixedName(name),ref,start_ix,num_val, LAST); + return squeryarr(*m_table,m_parser_prefix, prefixedName(name),ref,start_ix,num_val, LAST); } void @@ -1599,25 +1706,25 @@ ParmParse::addarr (const char* name, const std::vector& ref) void ParmParse::getkth (const char* name, int k, Box& ref, int ival) const { - sgetval(*m_table, prefixedName(name),ref,ival,k); + sgetval(*m_table,m_parser_prefix, prefixedName(name),ref,ival,k); } void ParmParse::get (const char* name, Box& ref, int ival) const { - sgetval(*m_table, prefixedName(name),ref,ival, LAST); + sgetval(*m_table,m_parser_prefix, prefixedName(name),ref,ival, LAST); } int ParmParse::querykth (const char* name, int k, Box& ref, int ival) const { - return squeryval(*m_table, prefixedName(name),ref,ival,k); + return squeryval(*m_table,m_parser_prefix, prefixedName(name),ref,ival,k); } int ParmParse::query (const char* name, Box& ref, int ival) const { - return squeryval(*m_table, prefixedName(name),ref,ival, LAST); + return squeryval(*m_table,m_parser_prefix, prefixedName(name),ref,ival, LAST); } void @@ -1630,28 +1737,28 @@ void ParmParse::getktharr (const char* name, int k, std::vector& ref, int start_ix, int num_val) const { - sgetarr(*m_table, prefixedName(name),ref,start_ix,num_val,k); + sgetarr(*m_table,m_parser_prefix, prefixedName(name),ref,start_ix,num_val,k); } void ParmParse::getarr (const char* name, std::vector& ref, int start_ix, int num_val) const { - sgetarr(*m_table, prefixedName(name),ref,start_ix,num_val, LAST); + sgetarr(*m_table,m_parser_prefix, prefixedName(name),ref,start_ix,num_val, LAST); } int ParmParse::queryktharr (const char* name, int k, std::vector& ref, int start_ix, int num_val) const { - return squeryarr(*m_table, prefixedName(name),ref,start_ix, num_val,k); + return squeryarr(*m_table,m_parser_prefix, prefixedName(name),ref,start_ix, num_val,k); } int ParmParse::queryarr (const char* name, std::vector& ref, int start_ix, int num_val) const { - return squeryarr(*m_table, prefixedName(name),ref,start_ix,num_val, LAST); + return squeryarr(*m_table,m_parser_prefix, prefixedName(name),ref,start_ix,num_val, LAST); } void @@ -1705,4 +1812,68 @@ ParmParse::remove (const char* name) return static_cast(n); } +namespace { +template +bool squeryWithParser (const ParmParse::Table& table, + const std::string& parser_prefix, + const std::string& name, + T& ref) +{ + std::vector vals; + bool exist = squeryarr(table, parser_prefix, name, vals, + ParmParse::FIRST, ParmParse::ALL, ParmParse::LAST); + if (!exist) { return false; } + + std::string combined_string; + for (auto const& v : vals) { + combined_string.append(v); + } + return pp_parser(table, parser_prefix, name, combined_string, ref); +} +} + +int +ParmParse::queryWithParser (const char* name, int& ref) const +{ + return squeryWithParser(*m_table,m_parser_prefix,prefixedName(name),ref); +} + +int +ParmParse::queryWithParser (const char* name, long& ref) const +{ + return squeryWithParser(*m_table,m_parser_prefix,prefixedName(name),ref); +} + +int +ParmParse::queryWithParser (const char* name, long long& ref) const +{ + return squeryWithParser(*m_table,m_parser_prefix,prefixedName(name),ref); +} + +int +ParmParse::queryWithParser (const char* name, float& ref) const +{ + return squeryWithParser(*m_table,m_parser_prefix,prefixedName(name),ref); +} + +int +ParmParse::queryWithParser (const char* name, double& ref) const +{ + return squeryWithParser(*m_table,m_parser_prefix,prefixedName(name),ref); +} + +Parser +ParmParse::makeParser (std::string const& func, + Vector const& vars) const +{ + return pp_make_parser(func, vars, *m_table, m_parser_prefix); +} + +IParser +ParmParse::makeIParser (std::string const& func, + Vector const& vars) const +{ + return pp_make_parser(func, vars, *m_table, m_parser_prefix); +} + } From 80b0c7ea3dbc097fc0ddd263f544aacf812e4b13 Mon Sep 17 00:00:00 2001 From: Weiqun Zhang Date: Fri, 26 Jul 2024 11:11:10 -0700 Subject: [PATCH 3/5] IParser: Use long long int (#4046) * Use long long int as the underlying integer data type in IParser. * Extend number format to include `3e9`, `2.34e6`, `1'000'000`, etc. --- Docs/sphinx_documentation/source/Basics.rst | 6 +- Src/Base/Parser/AMReX_IParser.H | 11 +- Src/Base/Parser/AMReX_IParser.cpp | 2 +- Src/Base/Parser/AMReX_IParser_Exe.H | 96 ++++++------- Src/Base/Parser/AMReX_IParser_Y.H | 30 +++-- Src/Base/Parser/AMReX_IParser_Y.cpp | 129 +++++++++++------- Src/Base/Parser/amrex_iparser.l | 7 +- Src/Base/Parser/amrex_iparser.lex.nolint.H | 142 +++++++++++--------- Src/Base/Parser/amrex_iparser.tab.h | 2 +- Src/Base/Parser/amrex_iparser.y | 2 +- Tests/Parser/main.cpp | 31 ++++- 11 files changed, 271 insertions(+), 187 deletions(-) diff --git a/Docs/sphinx_documentation/source/Basics.rst b/Docs/sphinx_documentation/source/Basics.rst index 1502def6a88..da14577f26e 100644 --- a/Docs/sphinx_documentation/source/Basics.rst +++ b/Docs/sphinx_documentation/source/Basics.rst @@ -594,7 +594,11 @@ Besides :cpp:`amrex::Parser` for floating point numbers, AMReX also provides similarity, but floating point number specific functions (e.g., ``sqrt``, ``sin``, etc.) are not supported in ``IParser``. In addition to ``/`` whose result truncates towards zero, the integer parser also supports ``//`` whose -result truncates towards negative infinity. +result truncates towards negative infinity. Single quotes ``'`` are allowed +as a separator for :cpp:`IParser` numbers just like C++ integer +literals. Additionally, a floating point like number with a positive +exponent may be accepted as an integer if it is reasonable to do so. For +example, it's okay to have ``1.234e3``, but ``1.234e2`` is an error. .. _sec:basics:initialize: diff --git a/Src/Base/Parser/AMReX_IParser.H b/Src/Base/Parser/AMReX_IParser.H index 6cf1e5b2b0f..9b3f8af6f34 100644 --- a/Src/Base/Parser/AMReX_IParser.H +++ b/Src/Base/Parser/AMReX_IParser.H @@ -18,7 +18,7 @@ struct IParserExecutor { template = 0> [[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE - int operator() () const noexcept + long long operator() () const noexcept { AMREX_IF_ON_DEVICE((return iparser_exe_eval(m_device_executor, nullptr);)) AMREX_IF_ON_HOST((return iparser_exe_eval(m_host_executor, nullptr);)) @@ -26,16 +26,17 @@ struct IParserExecutor template [[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE - std::enable_if_t + std::enable_if_t...>, + long long> operator() (Ts... var) const noexcept { - amrex::GpuArray l_var{var...}; + amrex::GpuArray l_var{var...}; AMREX_IF_ON_DEVICE((return iparser_exe_eval(m_device_executor, l_var.data());)) AMREX_IF_ON_HOST((return iparser_exe_eval(m_host_executor, l_var.data());)) } [[nodiscard]] AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE - int operator() (GpuArray const& var) const noexcept + long long operator() (GpuArray const& var) const noexcept { AMREX_IF_ON_DEVICE((return iparser_exe_eval(m_device_executor, var.data());)) AMREX_IF_ON_HOST((return iparser_exe_eval(m_host_executor, var.data());)) @@ -62,7 +63,7 @@ public: explicit operator bool () const; - void setConstant (std::string const& name, int c); + void setConstant (std::string const& name, long long c); void registerVariables (Vector const& vars); diff --git a/Src/Base/Parser/AMReX_IParser.cpp b/Src/Base/Parser/AMReX_IParser.cpp index 0845d47b842..ecda330f198 100644 --- a/Src/Base/Parser/AMReX_IParser.cpp +++ b/Src/Base/Parser/AMReX_IParser.cpp @@ -54,7 +54,7 @@ IParser::operator bool () const } void -IParser::setConstant (std::string const& name, int c) +IParser::setConstant (std::string const& name, long long c) { if (m_data && m_data->m_iparser) { iparser_setconst(m_data->m_iparser, name.c_str(), c); diff --git a/Src/Base/Parser/AMReX_IParser_Exe.H b/Src/Base/Parser/AMReX_IParser_Exe.H index 67756a93599..e7e41c44d48 100644 --- a/Src/Base/Parser/AMReX_IParser_Exe.H +++ b/Src/Base/Parser/AMReX_IParser_Exe.H @@ -62,7 +62,7 @@ struct alignas(8) IParserExeNull { struct alignas(8) IParserExeNumber { enum iparser_exe_t type = IPARSER_EXE_NUMBER; - int v; + long long v; }; struct alignas(8) IParserExeSymbol { @@ -76,7 +76,7 @@ struct alignas(8) IParserExeADD { struct alignas(8) IParserExeSUB { enum iparser_exe_t type = IPARSER_EXE_SUB; - int sign; + long long sign; }; struct alignas(8) IParserExeMUL { @@ -113,31 +113,31 @@ struct alignas(8) IParserExeF2_B { struct alignas(8) IParserExeADD_VP { enum iparser_exe_t type = IPARSER_EXE_ADD_VP; int i; - int v; + long long v; }; struct alignas(8) IParserExeSUB_VP { enum iparser_exe_t type = IPARSER_EXE_SUB_VP; int i; - int v; + long long v; }; struct alignas(8) IParserExeMUL_VP { enum iparser_exe_t type = IPARSER_EXE_MUL_VP; int i; - int v; + long long v; }; struct alignas(8) IParserExeDIV_VP { enum iparser_exe_t type = IPARSER_EXE_DIV_VP; int i; - int v; + long long v; }; struct alignas(8) IParserExeDIV_PV { enum iparser_exe_t type = IPARSER_EXE_DIV_PV; int i; - int v; + long long v; }; struct alignas(8) IParserExeADD_PP { @@ -171,27 +171,27 @@ struct alignas(8) IParserExeNEG_P { struct alignas(8) IParserExeADD_VN { enum iparser_exe_t type = IPARSER_EXE_ADD_VN; - int v; + long long v; }; struct alignas(8) IParserExeSUB_VN { enum iparser_exe_t type = IPARSER_EXE_SUB_VN; - int v; + long long v; }; struct alignas(8) IParserExeMUL_VN { enum iparser_exe_t type = IPARSER_EXE_MUL_VN; - int v; + long long v; }; struct alignas(8) IParserExeDIV_VN { enum iparser_exe_t type = IPARSER_EXE_DIV_VN; - int v; + long long v; }; struct alignas(8) IParserExeDIV_NV { enum iparser_exe_t type = IPARSER_EXE_DIV_NV; - int v; + long long v; }; struct alignas(8) IParserExeADD_PN { @@ -202,7 +202,7 @@ struct alignas(8) IParserExeADD_PN { struct alignas(8) IParserExeSUB_PN { enum iparser_exe_t type = IPARSER_EXE_SUB_PN; int i; - int sign; + long long sign; }; struct alignas(8) IParserExeMUL_PN { @@ -229,19 +229,19 @@ struct alignas(8) IParserExeJUMP { template struct IParserStack { - int m_data[N]; + long long m_data[N]; int m_size = 0; - constexpr void push (int v) { m_data[m_size++] = v; } + constexpr void push (long long v) { m_data[m_size++] = v; } constexpr void pop () { --m_size; } - [[nodiscard]] constexpr int const& top () const { return m_data[m_size-1]; } - [[nodiscard]] constexpr int & top () { return m_data[m_size-1]; } - [[nodiscard]] constexpr int operator[] (int i) const { return m_data[i]; } + [[nodiscard]] constexpr long long const& top () const { return m_data[m_size-1]; } + [[nodiscard]] constexpr long long & top () { return m_data[m_size-1]; } + [[nodiscard]] constexpr long long operator[] (int i) const { return m_data[i]; } }; AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE -int iparser_exe_eval (const char* p, int const* x) +long long iparser_exe_eval (const char* p, long long const* x) { - if (p == nullptr) { return std::numeric_limits::max(); } + if (p == nullptr) { return std::numeric_limits::max(); } IParserStack pstack; while (*((iparser_exe_t*)p) != IPARSER_EXE_NULL) { @@ -256,14 +256,14 @@ int iparser_exe_eval (const char* p, int const* x) case IPARSER_EXE_SYMBOL: { int i = ((IParserExeSymbol*)p)->i; - int d = AMREX_IPARSER_GET_DATA(i); + auto d = AMREX_IPARSER_GET_DATA(i); pstack.push(d); p += sizeof(IParserExeSymbol); break; } case IPARSER_EXE_ADD: { - int b = pstack.top(); + auto b = pstack.top(); pstack.pop(); pstack.top() += b; p += sizeof(IParserExeADD); @@ -271,7 +271,7 @@ int iparser_exe_eval (const char* p, int const* x) } case IPARSER_EXE_SUB: { - int b = pstack.top(); + auto b = pstack.top(); pstack.pop(); pstack.top() = (pstack.top() - b) * (((IParserExeSUB*)p)->sign); p += sizeof(IParserExeSUB); @@ -279,7 +279,7 @@ int iparser_exe_eval (const char* p, int const* x) } case IPARSER_EXE_MUL: { - int b = pstack.top(); + auto b = pstack.top(); pstack.pop(); pstack.top() *= b; p += sizeof(IParserExeMUL); @@ -287,7 +287,7 @@ int iparser_exe_eval (const char* p, int const* x) } case IPARSER_EXE_DIV_F: { - int v = pstack.top(); + auto v = pstack.top(); pstack.pop(); pstack.top() /= v; p += sizeof(IParserExeDIV_F); @@ -295,7 +295,7 @@ int iparser_exe_eval (const char* p, int const* x) } case IPARSER_EXE_DIV_B: { - int v = pstack.top(); + auto v = pstack.top(); pstack.pop(); pstack.top() = v / pstack.top(); p += sizeof(IParserExeDIV_B); @@ -315,7 +315,7 @@ int iparser_exe_eval (const char* p, int const* x) } case IPARSER_EXE_F2_F: { - int v = pstack.top(); + auto v = pstack.top(); pstack.pop(); pstack.top() = iparser_call_f2(((IParserExeF2_F*)p)->ftype, pstack.top(), v); p += sizeof(IParserExeF2_F); @@ -323,7 +323,7 @@ int iparser_exe_eval (const char* p, int const* x) } case IPARSER_EXE_F2_B: { - int v = pstack.top(); + auto v = pstack.top(); pstack.pop(); pstack.top() = iparser_call_f2(((IParserExeF2_B*)p)->ftype, v, pstack.top()); p += sizeof(IParserExeF2_B); @@ -332,7 +332,7 @@ int iparser_exe_eval (const char* p, int const* x) case IPARSER_EXE_ADD_VP: { int i = ((IParserExeADD_VP*)p)->i; - int d = AMREX_IPARSER_GET_DATA(i); + auto d = AMREX_IPARSER_GET_DATA(i); pstack.push(((IParserExeADD_VP*)p)->v + d); p += sizeof(IParserExeADD_VP); break; @@ -340,7 +340,7 @@ int iparser_exe_eval (const char* p, int const* x) case IPARSER_EXE_SUB_VP: { int i = ((IParserExeSUB_VP*)p)->i; - int d = AMREX_IPARSER_GET_DATA(i); + auto d = AMREX_IPARSER_GET_DATA(i); pstack.push(((IParserExeSUB_VP*)p)->v - d); p += sizeof(IParserExeSUB_VP); break; @@ -348,7 +348,7 @@ int iparser_exe_eval (const char* p, int const* x) case IPARSER_EXE_MUL_VP: { int i = ((IParserExeMUL_VP*)p)->i; - int d = AMREX_IPARSER_GET_DATA(i); + auto d = AMREX_IPARSER_GET_DATA(i); pstack.push(((IParserExeMUL_VP*)p)->v * d); p += sizeof(IParserExeMUL_VP); break; @@ -356,7 +356,7 @@ int iparser_exe_eval (const char* p, int const* x) case IPARSER_EXE_DIV_VP: { int i = ((IParserExeDIV_VP*)p)->i; - int d = AMREX_IPARSER_GET_DATA(i); + auto d = AMREX_IPARSER_GET_DATA(i); pstack.push(((IParserExeDIV_VP*)p)->v / d); p += sizeof(IParserExeDIV_VP); break; @@ -364,7 +364,7 @@ int iparser_exe_eval (const char* p, int const* x) case IPARSER_EXE_DIV_PV: { int i = ((IParserExeDIV_PV*)p)->i; - int d = AMREX_IPARSER_GET_DATA(i); + auto d = AMREX_IPARSER_GET_DATA(i); pstack.push(d / ((IParserExeDIV_PV*)p)->v); p += sizeof(IParserExeDIV_PV); break; @@ -372,9 +372,9 @@ int iparser_exe_eval (const char* p, int const* x) case IPARSER_EXE_ADD_PP: { int i = ((IParserExeADD_PP*)p)->i1; - int d1 = AMREX_IPARSER_GET_DATA(i); + auto d1 = AMREX_IPARSER_GET_DATA(i); i = ((IParserExeADD_PP*)p)->i2; - int d2 = AMREX_IPARSER_GET_DATA(i); + auto d2 = AMREX_IPARSER_GET_DATA(i); pstack.push(d1+d2); p += sizeof(IParserExeADD_PP); break; @@ -382,9 +382,9 @@ int iparser_exe_eval (const char* p, int const* x) case IPARSER_EXE_SUB_PP: { int i = ((IParserExeSUB_PP*)p)->i1; - int d1 = AMREX_IPARSER_GET_DATA(i); + auto d1 = AMREX_IPARSER_GET_DATA(i); i = ((IParserExeSUB_PP*)p)->i2; - int d2 = AMREX_IPARSER_GET_DATA(i); + auto d2 = AMREX_IPARSER_GET_DATA(i); pstack.push(d1-d2); p += sizeof(IParserExeSUB_PP); break; @@ -392,9 +392,9 @@ int iparser_exe_eval (const char* p, int const* x) case IPARSER_EXE_MUL_PP: { int i = ((IParserExeMUL_PP*)p)->i1; - int d1 = AMREX_IPARSER_GET_DATA(i); + auto d1 = AMREX_IPARSER_GET_DATA(i); i = ((IParserExeMUL_PP*)p)->i2; - int d2 = AMREX_IPARSER_GET_DATA(i); + auto d2 = AMREX_IPARSER_GET_DATA(i); pstack.push(d1*d2); p += sizeof(IParserExeMUL_PP); break; @@ -402,9 +402,9 @@ int iparser_exe_eval (const char* p, int const* x) case IPARSER_EXE_DIV_PP: { int i = ((IParserExeDIV_PP*)p)->i1; - int d1 = AMREX_IPARSER_GET_DATA(i); + auto d1 = AMREX_IPARSER_GET_DATA(i); i = ((IParserExeDIV_PP*)p)->i2; - int d2 = AMREX_IPARSER_GET_DATA(i); + auto d2 = AMREX_IPARSER_GET_DATA(i); pstack.push(d1/d2); p += sizeof(IParserExeDIV_PP); break; @@ -412,7 +412,7 @@ int iparser_exe_eval (const char* p, int const* x) case IPARSER_EXE_NEG_P: { int i = ((IParserExeNEG_P*)p)->i; - int d = AMREX_IPARSER_GET_DATA(i); + auto d = AMREX_IPARSER_GET_DATA(i); pstack.push(-d); p += sizeof(IParserExeNEG_P); break; @@ -450,7 +450,7 @@ int iparser_exe_eval (const char* p, int const* x) case IPARSER_EXE_ADD_PN: { int i = ((IParserExeADD_PN*)p)->i; - int d = AMREX_IPARSER_GET_DATA(i); + auto d = AMREX_IPARSER_GET_DATA(i); pstack.top() += d; p += sizeof(IParserExeADD_PN); break; @@ -458,7 +458,7 @@ int iparser_exe_eval (const char* p, int const* x) case IPARSER_EXE_SUB_PN: { int i = ((IParserExeSUB_PN*)p)->i; - int d = AMREX_IPARSER_GET_DATA(i); + auto d = AMREX_IPARSER_GET_DATA(i); pstack.top() = (d - pstack.top()) * (((IParserExeSUB_PN*)p)->sign); p += sizeof(IParserExeSUB_PN); break; @@ -466,7 +466,7 @@ int iparser_exe_eval (const char* p, int const* x) case IPARSER_EXE_MUL_PN: { int i = ((IParserExeMUL_PN*)p)->i; - int d = AMREX_IPARSER_GET_DATA(i); + auto d = AMREX_IPARSER_GET_DATA(i); pstack.top() *= d; p += sizeof(IParserExeMUL_PN); break; @@ -474,7 +474,7 @@ int iparser_exe_eval (const char* p, int const* x) case IPARSER_EXE_DIV_PN: { int i = ((IParserExeDIV_PN*)p)->i; - int d = AMREX_IPARSER_GET_DATA(i); + auto d = AMREX_IPARSER_GET_DATA(i); if (((IParserExeDIV_PN*)p)->reverse) { pstack.top() /= d; } else { @@ -485,9 +485,9 @@ int iparser_exe_eval (const char* p, int const* x) } case IPARSER_EXE_IF: { - int cond = pstack.top(); + auto cond = pstack.top(); pstack.pop(); - if (cond == 0.0) { // false branch + if (cond == 0) { // false branch p += ((IParserExeIF*)p)->offset; } p += sizeof(IParserExeIF); diff --git a/Src/Base/Parser/AMReX_IParser_Y.H b/Src/Base/Parser/AMReX_IParser_Y.H index 50eb5de39ec..79b6cd7551b 100644 --- a/Src/Base/Parser/AMReX_IParser_Y.H +++ b/Src/Base/Parser/AMReX_IParser_Y.H @@ -75,7 +75,7 @@ enum iparser_node_t { union iparser_nvp { struct iparser_node* n; - int v; + long long v; int ip; }; @@ -89,7 +89,7 @@ struct iparser_node { struct iparser_number { enum iparser_node_t type; - int value; + long long value; }; struct iparser_symbol { @@ -134,7 +134,7 @@ void iparser_defexpr (struct iparser_node* body); struct iparser_symbol* iparser_makesymbol (char* name); struct iparser_node* iparser_newnode (enum iparser_node_t type, struct iparser_node* l, struct iparser_node* r); -struct iparser_node* iparser_newnumber (int d); +struct iparser_node* iparser_newnumber (long long d); struct iparser_node* iparser_newsymbol (struct iparser_symbol* sym); struct iparser_node* iparser_newf1 (enum iparser_f1_t ftype, struct iparser_node* l); struct iparser_node* iparser_newf2 (enum iparser_f2_t ftype, struct iparser_node* l, @@ -164,7 +164,7 @@ struct amrex_iparser* iparser_dup (struct amrex_iparser* source); struct iparser_node* iparser_ast_dup (struct amrex_iparser* iparser, struct iparser_node* node, int move); void iparser_regvar (struct amrex_iparser* iparser, char const* name, int i); -void iparser_setconst (struct amrex_iparser* iparser, char const* name, int c); +void iparser_setconst (struct amrex_iparser* iparser, char const* name, long long c); void iparser_print (struct amrex_iparser* iparser); std::set iparser_get_symbols (struct amrex_iparser* iparser); int iparser_depth (struct amrex_iparser* iparser); @@ -174,27 +174,27 @@ void iparser_ast_optimize (struct iparser_node* node); std::size_t iparser_ast_size (struct iparser_node* node); void iparser_ast_print (struct iparser_node* node, std::string const& space, AllPrint& printer); void iparser_ast_regvar (struct iparser_node* node, char const* name, int i); -void iparser_ast_setconst (struct iparser_node* node, char const* name, int c); +void iparser_ast_setconst (struct iparser_node* node, char const* name, long long c); void iparser_ast_get_symbols (struct iparser_node* node, std::set& symbols, std::set& local_symbols); int iparser_ast_depth (struct iparser_node* node); /*******************************************************************/ -AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int -iparser_call_f1 (enum iparser_f1_t /*type*/, int a) +AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE long long +iparser_call_f1 (enum iparser_f1_t /*type*/, long long a) { /// There is only one type for now return std::abs(a); } -AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int -iparser_call_f2 (enum iparser_f2_t type, int a, int b) +AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE long long +iparser_call_f2 (enum iparser_f2_t type, long long a, long long b) { switch (type) { case IPARSER_FLRDIV: { - int r = a/b; + long long r = a/b; if (r*b == a || (a < 0 && b < 0) || (a > 0 && b > 0)) { return r; } else { @@ -206,13 +206,13 @@ iparser_call_f2 (enum iparser_f2_t type, int a, int b) if (b < 0) { return 0; } else { - int r = 1; + long long r = 1; while (b != 0) { if (b & 1) { r *= a; } b >>= 1; - a *= a; + if (b > 0) { a *= a; } // to avoid overflow } return r; } @@ -243,13 +243,15 @@ iparser_call_f2 (enum iparser_f2_t type, int a, int b) } } -AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int -iparser_call_f3 (enum iparser_f3_t /*type*/, int a, int b, int c) +AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE long long +iparser_call_f3 (enum iparser_f3_t /*type*/, long long a, long long b, long long c) { // There is only one type currently return (a != 0) ? b : c; } +long long iparser_atoll (const char* str); + } #endif diff --git a/Src/Base/Parser/AMReX_IParser_Y.cpp b/Src/Base/Parser/AMReX_IParser_Y.cpp index cfb036de96e..00cca1717f0 100644 --- a/Src/Base/Parser/AMReX_IParser_Y.cpp +++ b/Src/Base/Parser/AMReX_IParser_Y.cpp @@ -51,7 +51,7 @@ iparser_newnode (enum iparser_node_t type, struct iparser_node* l, struct iparse } struct iparser_node* -iparser_newnumber (int d) +iparser_newnumber (long long d) { auto *r = (struct iparser_number*) std::malloc(sizeof(struct iparser_number)); r->type = IPARSER_NUMBER; @@ -398,7 +398,7 @@ iparser_ast_optimize (struct iparser_node* node) if (node->l->type == IPARSER_NUMBER && node->r->type == IPARSER_NUMBER) { - int v = ((struct iparser_number*)(node->l))->value + auto v= ((struct iparser_number*)(node->l))->value + ((struct iparser_number*)(node->r))->value; ((struct iparser_number*)node)->type = IPARSER_NUMBER; ((struct iparser_number*)node)->value = v; @@ -428,28 +428,28 @@ iparser_ast_optimize (struct iparser_node* node) else if (node->l->type == IPARSER_NUMBER && node->r->type == IPARSER_ADD_VP) { - int v = ((struct iparser_number*)(node->l))->value + IPARSER_EVAL_R(node); + auto v = ((struct iparser_number*)(node->l))->value + IPARSER_EVAL_R(node); IPARSER_MOVEUP_R(node, v); node->type = IPARSER_ADD_VP; } else if (node->l->type == IPARSER_NUMBER && node->r->type == IPARSER_SUB_VP) { - int v = ((struct iparser_number*)(node->l))->value + IPARSER_EVAL_R(node); + auto v = ((struct iparser_number*)(node->l))->value + IPARSER_EVAL_R(node); IPARSER_MOVEUP_R(node, v); node->type = IPARSER_SUB_VP; } else if (node->l->type == IPARSER_ADD_VP && node->r->type == IPARSER_NUMBER) { - int v = IPARSER_EVAL_L(node) + ((struct iparser_number*)(node->r))->value; + auto v = IPARSER_EVAL_L(node) + ((struct iparser_number*)(node->r))->value; IPARSER_MOVEUP_L(node, v); node->type = IPARSER_ADD_VP; } else if (node->l->type == IPARSER_SUB_VP && node->r->type == IPARSER_NUMBER) { - int v = IPARSER_EVAL_L(node) + ((struct iparser_number*)(node->r))->value; + auto v = IPARSER_EVAL_L(node) + ((struct iparser_number*)(node->r))->value; IPARSER_MOVEUP_L(node, v); node->type = IPARSER_SUB_VP; } @@ -458,14 +458,14 @@ iparser_ast_optimize (struct iparser_node* node) { if (node->r->l->type == IPARSER_NUMBER) { // #l + (#rl + node_rr) -> (#l + #rl) + node_rr, same type - int v = ((struct iparser_number*)(node->l))->value + auto v= ((struct iparser_number*)(node->l))->value + ((struct iparser_number*)(node->r->l))->value; node->r = node->r->r; ((struct iparser_number*)(node->l))->value = v; } else if (node->r->r->type == IPARSER_NUMBER) { // #l + (node_rl + #rr) -> (#l + #rr) + node_rl, same type - int v = ((struct iparser_number*)(node->l))->value + auto v= ((struct iparser_number*)(node->l))->value + ((struct iparser_number*)(node->r->r))->value; node->r = node->r->l; ((struct iparser_number*)(node->l))->value = v; @@ -476,7 +476,7 @@ iparser_ast_optimize (struct iparser_node* node) { if (node->r->l->type == IPARSER_NUMBER) { // #l + (#rl - node_rr) -> (#l + #rl) - node_rr, type change - int v = ((struct iparser_number*)(node->l))->value + auto v= ((struct iparser_number*)(node->l))->value + ((struct iparser_number*)(node->r->l))->value; node->r = node->r->r; ((struct iparser_number*)(node->l))->value = v; @@ -484,7 +484,7 @@ iparser_ast_optimize (struct iparser_node* node) } else if (node->r->r->type == IPARSER_NUMBER) { // #l + (node_rl - #rr) -> (#l - #rr) + node_rl, same type - int v = ((struct iparser_number*)(node->l))->value + auto v= ((struct iparser_number*)(node->l))->value - ((struct iparser_number*)(node->r->r))->value; node->r = node->r->l; ((struct iparser_number*)(node->l))->value = v; @@ -495,14 +495,14 @@ iparser_ast_optimize (struct iparser_node* node) { if (node->l->l->type == IPARSER_NUMBER) { // (#ll + node_lr) + #r -> nodel_lr + (#ll + #r), same type - int v = ((struct iparser_number*)(node->l->l))->value + auto v= ((struct iparser_number*)(node->l->l))->value + ((struct iparser_number*)(node->r))->value; node->l = node->l->r; ((struct iparser_number*)(node->r))->value = v; } else if (node->l->r->type == IPARSER_NUMBER) { // (node_ll + #lr) + #r -> node_ll + (#lr + #r), same type - int v = ((struct iparser_number*)(node->l->r))->value + auto v= ((struct iparser_number*)(node->l->r))->value + ((struct iparser_number*)(node->r))->value; node->l = node->l->l; ((struct iparser_number*)(node->r))->value = v; @@ -513,7 +513,7 @@ iparser_ast_optimize (struct iparser_node* node) { if (node->l->l->type == IPARSER_NUMBER) { // (#ll - node_lr) + #r -> (#ll + #r) - node_lr, type change - int v = ((struct iparser_number*)(node->l->l))->value + auto v= ((struct iparser_number*)(node->l->l))->value + ((struct iparser_number*)(node->r))->value; node->r = node->l->r; ((struct iparser_number*)(node->l))->type = IPARSER_NUMBER; @@ -522,7 +522,7 @@ iparser_ast_optimize (struct iparser_node* node) } else if (node->l->r->type == IPARSER_NUMBER) { // (node_ll - #lr) + #r -> node_ll + (#r - #lr), same type - int v = ((struct iparser_number*)(node->r))->value + auto v= ((struct iparser_number*)(node->r))->value - ((struct iparser_number*)(node->l->r))->value; node->l = node->l->l; ((struct iparser_number*)(node->r))->value = v; @@ -536,7 +536,7 @@ iparser_ast_optimize (struct iparser_node* node) if (node->l->type == IPARSER_NUMBER && node->r->type == IPARSER_NUMBER) { - int v = ((struct iparser_number*)(node->l))->value + auto v= ((struct iparser_number*)(node->l))->value - ((struct iparser_number*)(node->r))->value; ((struct iparser_number*)node)->type = IPARSER_NUMBER; ((struct iparser_number*)node)->value = v; @@ -566,28 +566,28 @@ iparser_ast_optimize (struct iparser_node* node) else if (node->l->type == IPARSER_NUMBER && node->r->type == IPARSER_ADD_VP) { - int v = ((struct iparser_number*)(node->l))->value - IPARSER_EVAL_R(node); + auto v= ((struct iparser_number*)(node->l))->value - IPARSER_EVAL_R(node); IPARSER_MOVEUP_R(node, v); node->type = IPARSER_SUB_VP; } else if (node->l->type == IPARSER_NUMBER && node->r->type == IPARSER_SUB_VP) { - int v = ((struct iparser_number*)(node->l))->value - IPARSER_EVAL_R(node); + auto v= ((struct iparser_number*)(node->l))->value - IPARSER_EVAL_R(node); IPARSER_MOVEUP_R(node, v); node->type = IPARSER_ADD_VP; } else if (node->l->type == IPARSER_ADD_VP && node->r->type == IPARSER_NUMBER) { - int v = IPARSER_EVAL_L(node) - ((struct iparser_number*)(node->r))->value; + auto v= IPARSER_EVAL_L(node) - ((struct iparser_number*)(node->r))->value; IPARSER_MOVEUP_L(node, v); node->type = IPARSER_ADD_VP; } else if (node->l->type == IPARSER_SUB_VP && node->r->type == IPARSER_NUMBER) { - int v = IPARSER_EVAL_L(node) - ((struct iparser_number*)(node->r))->value; + auto v= IPARSER_EVAL_L(node) - ((struct iparser_number*)(node->r))->value; IPARSER_MOVEUP_L(node, v); node->type = IPARSER_SUB_VP; } @@ -596,14 +596,14 @@ iparser_ast_optimize (struct iparser_node* node) { if (node->r->l->type == IPARSER_NUMBER) { // #l - (#rl + node_rr) -> (#l - #rl) - node_rr, same type - int v = ((struct iparser_number*)(node->l))->value + auto v= ((struct iparser_number*)(node->l))->value - ((struct iparser_number*)(node->r->l))->value; node->r = node->r->r; ((struct iparser_number*)(node->l))->value = v; } else if (node->r->r->type == IPARSER_NUMBER) { // #l - (node_rl + #rr) -> (#l - #rr) - node_rl, same type - int v = ((struct iparser_number*)(node->l))->value + auto v= ((struct iparser_number*)(node->l))->value - ((struct iparser_number*)(node->r->r))->value; node->r = node->r->l; ((struct iparser_number*)(node->l))->value = v; @@ -614,7 +614,7 @@ iparser_ast_optimize (struct iparser_node* node) { if (node->r->l->type == IPARSER_NUMBER) { // #l - (#rl - node_rr) -> (#l - #rl) + node_rr, type change - int v = ((struct iparser_number*)(node->l))->value + auto v= ((struct iparser_number*)(node->l))->value - ((struct iparser_number*)(node->r->l))->value; node->r = node->r->r; ((struct iparser_number*)(node->l))->value = v; @@ -622,7 +622,7 @@ iparser_ast_optimize (struct iparser_node* node) } else if (node->r->r->type == IPARSER_NUMBER) { // #l - (node_rl - #rr) -> (#l + #rr) - node_rl, same type - int v = ((struct iparser_number*)(node->l))->value + auto v= ((struct iparser_number*)(node->l))->value + ((struct iparser_number*)(node->r->r))->value; node->r = node->r->l; ((struct iparser_number*)(node->l))->value = v; @@ -633,14 +633,14 @@ iparser_ast_optimize (struct iparser_node* node) { if (node->l->l->type == IPARSER_NUMBER) { // (#ll + node_lr) - #r -> node_lr - (#r - #ll), same type - int v = ((struct iparser_number*)(node->r))->value + auto v= ((struct iparser_number*)(node->r))->value - ((struct iparser_number*)(node->l->l))->value; node->l = node->l->r; ((struct iparser_number*)(node->r))->value = v; } else if (node->l->r->type == IPARSER_NUMBER) { // (node_ll + #lr) - #r -> node_ll - (#r - #lr), same type - int v = ((struct iparser_number*)(node->r))->value + auto v= ((struct iparser_number*)(node->r))->value - ((struct iparser_number*)(node->l->r))->value; node->l = node->l->l; ((struct iparser_number*)(node->r))->value = v; @@ -651,7 +651,7 @@ iparser_ast_optimize (struct iparser_node* node) { if (node->l->l->type == IPARSER_NUMBER) { // (#ll - node_lr) - #r -> (#ll - #r) - node_lr, type change - int v = ((struct iparser_number*)(node->l->l))->value + auto v= ((struct iparser_number*)(node->l->l))->value - ((struct iparser_number*)(node->r))->value; node->r = node->l->r; node->l->type = IPARSER_NUMBER; @@ -659,7 +659,7 @@ iparser_ast_optimize (struct iparser_node* node) } else if (node->l->r->type == IPARSER_NUMBER) { // (node_ll - #lr) - #r -> node_ll - (#r + #lr), same type - int v = ((struct iparser_number*)(node->r))->value + auto v= ((struct iparser_number*)(node->r))->value + ((struct iparser_number*)(node->l->r))->value; node->l = node->l->l; ((struct iparser_number*)(node->r))->value = v; @@ -673,7 +673,7 @@ iparser_ast_optimize (struct iparser_node* node) if (node->l->type == IPARSER_NUMBER && node->r->type == IPARSER_NUMBER) { - int v = ((struct iparser_number*)(node->l))->value + auto v= ((struct iparser_number*)(node->l))->value * ((struct iparser_number*)(node->r))->value; ((struct iparser_number*)node)->type = IPARSER_NUMBER; ((struct iparser_number*)node)->value = v; @@ -703,14 +703,14 @@ iparser_ast_optimize (struct iparser_node* node) else if (node->l->type == IPARSER_NUMBER && node->r->type == IPARSER_MUL_VP) { - int v = ((struct iparser_number*)(node->l))->value * IPARSER_EVAL_R(node); + auto v= ((struct iparser_number*)(node->l))->value * IPARSER_EVAL_R(node); IPARSER_MOVEUP_R(node, v); node->type = IPARSER_MUL_VP; } else if (node->l->type == IPARSER_MUL_VP && node->r->type == IPARSER_NUMBER) { - int v = IPARSER_EVAL_L(node) * ((struct iparser_number*)(node->r))->value; + auto v= IPARSER_EVAL_L(node) * ((struct iparser_number*)(node->r))->value; IPARSER_MOVEUP_L(node, v); node->type = IPARSER_MUL_VP; } @@ -719,14 +719,14 @@ iparser_ast_optimize (struct iparser_node* node) { if (node->r->l->type == IPARSER_NUMBER) { // #l * (#rl * node_rr) -> (#l * #rl) * node_rr, same type - int v = ((struct iparser_number*)(node->l))->value + auto v= ((struct iparser_number*)(node->l))->value * ((struct iparser_number*)(node->r->l))->value; node->r = node->r->r; ((struct iparser_number*)(node->l))->value = v; } else if (node->r->r->type == IPARSER_NUMBER) { // #l * (node_rl * #rr) -> (#l * #rr) * node_rl, same type - int v = ((struct iparser_number*)(node->l))->value + auto v= ((struct iparser_number*)(node->l))->value * ((struct iparser_number*)(node->r->r))->value; node->r = node->r->l; ((struct iparser_number*)(node->l))->value = v; @@ -737,14 +737,14 @@ iparser_ast_optimize (struct iparser_node* node) { if (node->l->l->type == IPARSER_NUMBER) { // (#ll * node_lr) * #r -> nodel_lr * (#ll * #r), same type - int v = ((struct iparser_number*)(node->l->l))->value + auto v= ((struct iparser_number*)(node->l->l))->value * ((struct iparser_number*)(node->r))->value; node->l = node->l->r; ((struct iparser_number*)(node->r))->value = v; } else if (node->l->r->type == IPARSER_NUMBER) { // (node_ll * #lr) * #r -> node_ll + (#lr * #r), same type - int v = ((struct iparser_number*)(node->l->r))->value + auto v= ((struct iparser_number*)(node->l->r))->value * ((struct iparser_number*)(node->r))->value; node->l = node->l->l; ((struct iparser_number*)(node->r))->value = v; @@ -758,7 +758,7 @@ iparser_ast_optimize (struct iparser_node* node) if (node->l->type == IPARSER_NUMBER && node->r->type == IPARSER_NUMBER) { - int v = ((struct iparser_number*)(node->l))->value + auto v= ((struct iparser_number*)(node->l))->value / ((struct iparser_number*)(node->r))->value; ((struct iparser_number*)node)->type = IPARSER_NUMBER; ((struct iparser_number*)node)->value = v; @@ -790,7 +790,7 @@ iparser_ast_optimize (struct iparser_node* node) iparser_ast_optimize(node->l); if (node->l->type == IPARSER_NUMBER) { - int v = -((struct iparser_number*)(node->l))->value; + auto v= -((struct iparser_number*)(node->l))->value; ((struct iparser_number*)node)->type = IPARSER_NUMBER; ((struct iparser_number*)node)->value = v; } @@ -876,7 +876,7 @@ iparser_ast_optimize (struct iparser_node* node) iparser_ast_optimize(node->l); if (node->l->type == IPARSER_NUMBER) { - int v = iparser_call_f1 + auto v= iparser_call_f1 (((struct iparser_f1*)node)->ftype, ((struct iparser_number*)(((struct iparser_f1*)node)->l))->value); ((struct iparser_number*)node)->type = IPARSER_NUMBER; @@ -889,7 +889,7 @@ iparser_ast_optimize (struct iparser_node* node) if (node->l->type == IPARSER_NUMBER && node->r->type == IPARSER_NUMBER) { - int v = iparser_call_f2 + auto v= iparser_call_f2 (((struct iparser_f2*)node)->ftype, ((struct iparser_number*)(((struct iparser_f2*)node)->l))->value, ((struct iparser_number*)(((struct iparser_f2*)node)->r))->value); @@ -905,7 +905,7 @@ iparser_ast_optimize (struct iparser_node* node) ((struct iparser_f3*)node)->n2->type == IPARSER_NUMBER && ((struct iparser_f3*)node)->n3->type == IPARSER_NUMBER) { - int v = iparser_call_f3 + auto v= iparser_call_f3 (((struct iparser_f3*)node)->ftype, ((struct iparser_number*)(((struct iparser_f3*)node)->n1))->value, ((struct iparser_number*)(((struct iparser_f3*)node)->n2))->value, @@ -918,7 +918,7 @@ iparser_ast_optimize (struct iparser_node* node) iparser_ast_optimize(node->r); if (node->r->type == IPARSER_NUMBER) { - int v = node->lvp.v + ((struct iparser_number*)(node->r))->value; + auto v= node->lvp.v + ((struct iparser_number*)(node->r))->value; ((struct iparser_number*)node)->type = IPARSER_NUMBER; ((struct iparser_number*)node)->value = v; } @@ -927,7 +927,7 @@ iparser_ast_optimize (struct iparser_node* node) iparser_ast_optimize(node->r); if (node->r->type == IPARSER_NUMBER) { - int v = node->lvp.v - ((struct iparser_number*)(node->r))->value; + auto v= node->lvp.v - ((struct iparser_number*)(node->r))->value; ((struct iparser_number*)node)->type = IPARSER_NUMBER; ((struct iparser_number*)node)->value = v; } @@ -936,7 +936,7 @@ iparser_ast_optimize (struct iparser_node* node) iparser_ast_optimize(node->r); if (node->r->type == IPARSER_NUMBER) { - int v = node->lvp.v * ((struct iparser_number*)(node->r))->value; + auto v= node->lvp.v * ((struct iparser_number*)(node->r))->value; ((struct iparser_number*)node)->type = IPARSER_NUMBER; ((struct iparser_number*)node)->value = v; } @@ -945,7 +945,7 @@ iparser_ast_optimize (struct iparser_node* node) iparser_ast_optimize(node->r); if (node->r->type == IPARSER_NUMBER) { - int v = node->lvp.v / ((struct iparser_number*)(node->r))->value; + auto v= node->lvp.v / ((struct iparser_number*)(node->r))->value; ((struct iparser_number*)node)->type = IPARSER_NUMBER; ((struct iparser_number*)node)->value = v; } @@ -954,7 +954,7 @@ iparser_ast_optimize (struct iparser_node* node) iparser_ast_optimize(node->r); if (node->r->type == IPARSER_NUMBER) { - int v = ((struct iparser_number*)(node->r))->value / node->lvp.v; + auto v= ((struct iparser_number*)(node->r))->value / node->lvp.v; ((struct iparser_number*)node)->type = IPARSER_NUMBER; ((struct iparser_number*)node)->value = v; } @@ -963,7 +963,7 @@ iparser_ast_optimize (struct iparser_node* node) iparser_ast_optimize(node->l); if (node->l->type == IPARSER_NUMBER) { - int v = -((struct iparser_number*)(node->l))->value; + auto v= -((struct iparser_number*)(node->l))->value; ((struct iparser_number*)node)->type = IPARSER_NUMBER; ((struct iparser_number*)node)->value = v; } @@ -1280,7 +1280,7 @@ iparser_ast_regvar (struct iparser_node* node, char const* name, int i) } } -void iparser_ast_setconst (struct iparser_node* node, char const* name, int c) +void iparser_ast_setconst (struct iparser_node* node, char const* name, long long c) { switch (node->type) { @@ -1396,7 +1396,7 @@ iparser_regvar (struct amrex_iparser* iparser, char const* name, int i) } void -iparser_setconst (struct amrex_iparser* iparser, char const* name, int c) +iparser_setconst (struct amrex_iparser* iparser, char const* name, long long c) { iparser_ast_setconst(iparser->ast, name, c); iparser_ast_optimize(iparser->ast); @@ -1427,4 +1427,39 @@ iparser_depth (struct amrex_iparser* iparser) return iparser_ast_depth(iparser->ast); } +long long +iparser_atoll (const char* str) +{ + std::string s(str); + s.erase(std::remove(s.begin(), s.end(), '\''), s.end()); + + auto pos_E = s.find('E'); + if (pos_E != std::string::npos) { + s[pos_E] = 'e'; + } + auto pos_e = s.find('e'); + if (pos_e != std::string::npos) { + std::string part_1 = s.substr(0, pos_e); + int ex = std::atoi(s.c_str()+pos_e+1); + auto pos_dot = part_1.find('.'); + if (pos_dot != std::string::npos) { + // iparser'number does not have more than one dot. + ex -= static_cast(part_1.size()-(pos_dot+1)); + part_1.erase(pos_dot,1); + } + if (ex < 0) { + throw std::runtime_error(std::string(str) + " is not an integer"); + } + part_1.resize(part_1.size()+ex,'0'); + return std::atoll(part_1.c_str()); + } else { + auto pos_dot = s.find('.'); + if (pos_dot != std::string::npos && pos_dot+1 < s.size()) { + throw std::runtime_error(std::string(str) + " is not an integer"); + } + // Note that atoll works as expected for numbers ending with `.` like `123.`. + return std::atoll(s.c_str()); + } +} + } diff --git a/Src/Base/Parser/amrex_iparser.l b/Src/Base/Parser/amrex_iparser.l index 3e90099ab7a..15f19b90525 100644 --- a/Src/Base/Parser/amrex_iparser.l +++ b/Src/Base/Parser/amrex_iparser.l @@ -15,6 +15,9 @@ /* Tokens NUMBER, SYMBOL, F1, POW, F2, etc. are defined in amrex_iparser.y. */ /* Types IPARSER_ABS, IPARSER_MIN etc. are defined in AMReX_IParser_y.H. */ + /* Used later to define NUMBER */ +EXP ([Ee][0-9]+) + %% "+" | @@ -51,7 +54,9 @@ [a-zA-Z_][a-zA-Z0-9_\.]* { amrex_iparserlval.s = amrex::iparser_makesymbol(amrex_iparsertext); return SYMBOL; } /* Number */ -[0-9]+ { amrex_iparserlval.d = std::atoi(amrex_iparsertext); return NUMBER; } +[0-9][0-9']* | +[0-9]+"."[0-9]*{EXP}? | +"."?[0-9]+{EXP}? { amrex_iparserlval.d = amrex::iparser_atoll(amrex_iparsertext); return NUMBER; } /* Special characters */ [ \t] /* ignore white space */ diff --git a/Src/Base/Parser/amrex_iparser.lex.nolint.H b/Src/Base/Parser/amrex_iparser.lex.nolint.H index 1ab963c5fc5..411c4210b8a 100644 --- a/Src/Base/Parser/amrex_iparser.lex.nolint.H +++ b/Src/Base/Parser/amrex_iparser.lex.nolint.H @@ -611,8 +611,8 @@ static void yynoreturn yy_fatal_error ( const char* msg ); (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; -#define YY_NUM_RULES 32 -#define YY_END_OF_BUFFER 33 +#define YY_NUM_RULES 34 +#define YY_END_OF_BUFFER 35 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -620,13 +620,14 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static const flex_int16_t yy_accept[50] = +static const flex_int16_t yy_accept[59] = { 0, - 0, 0, 33, 31, 28, 30, 31, 10, 11, 3, - 1, 6, 2, 4, 27, 9, 7, 5, 8, 26, - 31, 16, 26, 26, 26, 26, 20, 15, 14, 27, - 18, 19, 17, 26, 29, 26, 26, 26, 25, 26, - 26, 22, 12, 21, 26, 24, 23, 13, 0 + 0, 0, 35, 33, 30, 32, 33, 10, 11, 3, + 1, 6, 2, 33, 4, 27, 9, 7, 5, 8, + 26, 33, 16, 26, 26, 26, 26, 20, 15, 29, + 14, 27, 28, 27, 0, 18, 19, 17, 26, 31, + 26, 26, 26, 25, 26, 26, 22, 28, 0, 29, + 12, 21, 26, 24, 23, 28, 13, 0 } ; static const YY_CHAR yy_ec[256] = @@ -634,17 +635,17 @@ static const YY_CHAR yy_ec[256] = 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 4, 1, 1, 1, 1, 1, 1, 5, - 6, 7, 8, 9, 10, 11, 12, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 1, 14, 15, - 16, 17, 1, 1, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 1, 19, 1, 20, 18, 1, 21, 22, 18, 23, - - 18, 24, 18, 18, 25, 18, 18, 18, 26, 27, - 28, 18, 18, 29, 30, 18, 18, 18, 18, 31, - 18, 18, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 4, 1, 1, 1, 1, 1, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 1, 15, 16, + 17, 18, 1, 1, 19, 19, 19, 19, 20, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 1, 21, 1, 22, 19, 1, 23, 24, 19, 25, + + 20, 26, 19, 19, 27, 19, 19, 19, 28, 29, + 30, 19, 19, 31, 32, 19, 19, 19, 19, 33, + 19, 19, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -661,56 +662,64 @@ static const YY_CHAR yy_ec[256] = 1, 1, 1, 1, 1 } ; -static const YY_CHAR yy_meta[32] = +static const YY_CHAR yy_meta[34] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 2, 1, 2, 1, 1, 1, 1, 2, 1, 1, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2 + 1, 2, 1, 2, 1, 1, 1, 1, 2, 2, + 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2 } ; -static const flex_int16_t yy_base[51] = +static const flex_int16_t yy_base[60] = { 0, - 0, 0, 55, 56, 56, 56, 38, 56, 56, 46, - 56, 56, 56, 40, 38, 56, 34, 33, 32, 0, - 44, 56, 10, 12, 13, 17, 56, 56, 56, 32, - 56, 56, 56, 0, 56, 14, 20, 20, 0, 10, - 13, 0, 0, 0, 9, 0, 0, 0, 56, 33 + 0, 0, 76, 77, 77, 77, 58, 77, 77, 66, + 77, 77, 77, 59, 59, 29, 77, 54, 53, 52, + 0, 65, 77, 11, 13, 15, 36, 77, 77, 30, + 77, 32, 31, 42, 52, 77, 77, 77, 0, 77, + 33, 39, 39, 0, 28, 31, 0, 38, 45, 43, + 0, 0, 23, 0, 0, 39, 0, 77, 46 } ; -static const flex_int16_t yy_def[51] = +static const flex_int16_t yy_def[60] = { 0, - 49, 1, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 50, - 49, 49, 50, 50, 50, 50, 49, 49, 49, 49, - 49, 49, 49, 50, 49, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 0, 49 + 58, 1, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 59, 58, 58, 59, 59, 59, 59, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 59, 58, + 59, 59, 59, 59, 59, 59, 59, 58, 58, 58, + 59, 59, 59, 59, 59, 58, 59, 0, 58 } ; -static const flex_int16_t yy_nxt[88] = +static const flex_int16_t yy_nxt[111] = { 0, - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 4, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 23, 20, 20, 20, 24, 25, 20, 26, 20, 20, - 20, 36, 38, 40, 34, 39, 37, 41, 48, 47, - 46, 45, 44, 43, 30, 42, 35, 33, 32, 31, - 30, 29, 28, 27, 49, 3, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49 + 4, 5, 6, 7, 4, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 21, + 22, 23, 24, 21, 21, 21, 25, 26, 21, 27, + 21, 21, 21, 32, 41, 43, 32, 45, 44, 42, + 33, 46, 34, 30, 48, 32, 32, 39, 35, 35, + 49, 48, 56, 33, 57, 34, 50, 49, 56, 55, + 54, 35, 53, 52, 51, 50, 47, 40, 38, 37, + 36, 31, 30, 29, 28, 58, 3, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58 } ; -static const flex_int16_t yy_chk[88] = +static const flex_int16_t yy_chk[111] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 23, 24, 25, 50, 24, 23, 25, 45, 41, - 40, 38, 37, 36, 30, 26, 21, 19, 18, 17, - 15, 14, 10, 7, 3, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49 + 1, 1, 1, 16, 24, 25, 32, 26, 25, 24, + 16, 26, 16, 30, 33, 32, 34, 59, 16, 30, + 33, 48, 56, 34, 53, 34, 50, 48, 49, 46, + 45, 34, 43, 42, 41, 35, 27, 22, 20, 19, + 18, 15, 14, 10, 7, 3, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58 } ; static yy_state_type yy_last_accepting_state; @@ -735,6 +744,7 @@ char *yytext; #define YY_NO_INPUT 1 /* Tokens NUMBER, SYMBOL, F1, POW, F2, etc. are defined in amrex_iparser.y. */ /* Types IPARSER_ABS, IPARSER_MIN etc. are defined in AMReX_IParser_y.H. */ + /* Used later to define NUMBER */ #define INITIAL 0 @@ -975,13 +985,13 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 50 ) + if ( yy_current_state >= 59 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; ++yy_cp; } - while ( yy_current_state != 49 ); + while ( yy_current_state != 58 ); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); @@ -1080,30 +1090,32 @@ YY_RULE_SETUP YY_BREAK /* Number */ case 27: +case 28: +case 29: YY_RULE_SETUP -{ amrex_iparserlval.d = std::atoi(amrex_iparsertext); return NUMBER; } +{ amrex_iparserlval.d = amrex::iparser_atoll(amrex_iparsertext); return NUMBER; } YY_BREAK /* Special characters */ -case 28: +case 30: YY_RULE_SETUP /* ignore white space */ YY_BREAK -case 29: -/* rule 29 can match eol */ +case 31: +/* rule 31 can match eol */ YY_RULE_SETUP /* ignore line continuation */ YY_BREAK -case 30: -/* rule 30 can match eol */ +case 32: +/* rule 32 can match eol */ YY_RULE_SETUP { return EOL; } YY_BREAK /* everything else */ -case 31: +case 33: YY_RULE_SETUP { amrex_iparsererror("Unknown character %c", *amrex_iparsertext); } YY_BREAK -case 32: +case 34: YY_RULE_SETUP YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK @@ -1404,7 +1416,7 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 50 ) + if ( yy_current_state >= 59 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; @@ -1432,11 +1444,11 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 50 ) + if ( yy_current_state >= 59 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; - yy_is_jam = (yy_current_state == 49); + yy_is_jam = (yy_current_state == 58); return yy_is_jam ? 0 : yy_current_state; } diff --git a/Src/Base/Parser/amrex_iparser.tab.h b/Src/Base/Parser/amrex_iparser.tab.h index 58d607b3415..a72ba4aeed2 100644 --- a/Src/Base/Parser/amrex_iparser.tab.h +++ b/Src/Base/Parser/amrex_iparser.tab.h @@ -89,7 +89,7 @@ union AMREX_IPARSERSTYPE { struct amrex::iparser_node* n; - int d; + long long d; struct amrex::iparser_symbol* s; enum amrex::iparser_f1_t f1; enum amrex::iparser_f2_t f2; diff --git a/Src/Base/Parser/amrex_iparser.y b/Src/Base/Parser/amrex_iparser.y index a079c55698b..2cfd83d07af 100644 --- a/Src/Base/Parser/amrex_iparser.y +++ b/Src/Base/Parser/amrex_iparser.y @@ -26,7 +26,7 @@ int amrex_iparserlex (void); */ %union { struct amrex::iparser_node* n; - int d; + long long d; struct amrex::iparser_symbol* s; enum amrex::iparser_f1_t f1; enum amrex::iparser_f2_t f2; diff --git a/Tests/Parser/main.cpp b/Tests/Parser/main.cpp index 167c0a54a31..df82ba2f3f0 100644 --- a/Tests/Parser/main.cpp +++ b/Tests/Parser/main.cpp @@ -373,7 +373,7 @@ int main (int argc, char* argv[]) int count = 0; int x = 11; { - auto f = [&] (std::string const& s) -> int + auto f = [&] (std::string const& s) { amrex::Print() << count++ << ". Testing \"" << s << "\"\n"; IParser iparser(s); @@ -390,7 +390,7 @@ int main (int argc, char* argv[]) AMREX_ALWAYS_ASSERT(f("x/13/5") == ((x/13)/5)); AMREX_ALWAYS_ASSERT(f("13/x/5") == ((13/x)/5)); - auto g = [&] (std::string const& s, std::string const& c, int cv) -> int + auto g = [&] (std::string const& s, std::string const& c, int cv) { amrex::Print() << count++ << ". Testing \"" << s << "\"\n"; IParser iparser(s); @@ -408,7 +408,7 @@ int main (int argc, char* argv[]) AMREX_ALWAYS_ASSERT(g("x/b/5", "b", 13) == ((x/13)/5)); AMREX_ALWAYS_ASSERT(g("b/x/5", "b", 13) == ((13/x)/5)); - auto h = [&] (std::string const& s) -> int + auto h = [&] (std::string const& s) { amrex::Print() << count++ << ". Testing \"" << s << "\"\n"; IParser iparser(s); @@ -435,6 +435,31 @@ int main (int argc, char* argv[]) } } } + + AMREX_ALWAYS_ASSERT(h("123456789012345") == 123456789012345LL); + AMREX_ALWAYS_ASSERT(h("123456789012345.") == 123456789012345LL); + AMREX_ALWAYS_ASSERT(h("123'456'789'012'345") == 123456789012345LL); + AMREX_ALWAYS_ASSERT(h("1.23456789012345e14") == 123456789012345LL); + AMREX_ALWAYS_ASSERT(h("1.0E3") == 1000); + AMREX_ALWAYS_ASSERT(h("2**40") == 1024LL*1024LL*1024LL*1024LL); + + auto test_bad_number = [&] (std::string const& s) + { + amrex::Print() << count++ << ". Testing \"" << s << "\"\n"; + try { + IParser iparser(s); + auto exe = iparser.compileHost<0>(); + auto r = exe(); + amrex::ignore_unused(r); + return false; + } catch (std::runtime_error const& e) { + amrex::Print() << " Expected error: " << e.what() << '\n'; + return true; + } + }; + AMREX_ALWAYS_ASSERT(test_bad_number("1000000e-4")); + AMREX_ALWAYS_ASSERT(test_bad_number("1.234e2")); + AMREX_ALWAYS_ASSERT(test_bad_number("3.14")); } amrex::Print() << "\nAll IParser tests passed\n\n"; } From 6975ae0ed5ca51ec95268f323bdc705dab4fe571 Mon Sep 17 00:00:00 2001 From: Weiqun Zhang Date: Fri, 26 Jul 2024 14:08:20 -0700 Subject: [PATCH 4/5] ParmParse: Read IntVect & RealVect from array (#4050) --- Src/Base/AMReX_ParmParse.H | 23 +++++++++++++++++++ Src/Base/AMReX_ParmParse.cpp | 43 ++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/Src/Base/AMReX_ParmParse.H b/Src/Base/AMReX_ParmParse.H index 27d93eb67a2..d39a60d0bba 100644 --- a/Src/Base/AMReX_ParmParse.H +++ b/Src/Base/AMReX_ParmParse.H @@ -22,6 +22,7 @@ class Box; template class IntVectND; using IntVect = IntVectND; +class RealVect; // // ParmParse class implements a simple database for the storage and @@ -904,6 +905,28 @@ public: //! Add a key 'name' with vector of values 'ref' to the end of the PP table. void addarr (const char* name, const std::vector& refd); + /* + * \brief Query IntVect from array + * + * This reads IntVect from an array (e.g., `8 16 8`), not the format + * using parentheses (e.g., `(8,16,8)`). + */ + int queryarr (const char* name, IntVect& ref) const; + + /* + * \brief Get IntVect from array + * + * This reads IntVect from an array (e.g., `8 16 8`), not the format + * using parentheses (e.g., `(8,16,8)`). + */ + void getarr (const char* name, IntVect& ref) const; + + //! Query RealVect from array + int queryarr (const char* name, RealVect& ref) const; + + //! Get RealVect from array + void getarr (const char* name, RealVect& ref) const; + template void get (const char* name, std::array& ref) const { std::vector v; diff --git a/Src/Base/AMReX_ParmParse.cpp b/Src/Base/AMReX_ParmParse.cpp index f78da0e5e7e..669485f40d6 100644 --- a/Src/Base/AMReX_ParmParse.cpp +++ b/Src/Base/AMReX_ParmParse.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -1768,6 +1769,48 @@ ParmParse::addarr (const char* name, const std::vector& ref) } +int +ParmParse::queryarr (const char* name, IntVect& ref) const +{ + std::vector v; + int exist = this->queryarr(name, v); + AMREX_ALWAYS_ASSERT(v.size() == AMREX_SPACEDIM); + if (exist) { + for (int i = 0; i < AMREX_SPACEDIM; ++i) { ref[i] = v[i]; } + } + return exist; +} + +void +ParmParse::getarr (const char* name, IntVect& ref) const +{ + std::vector v; + this->getarr(name, v); + AMREX_ALWAYS_ASSERT(v.size() == AMREX_SPACEDIM); + for (int i = 0; i < AMREX_SPACEDIM; ++i) { ref[i] = v[i]; } +} + +int +ParmParse::queryarr (const char* name, RealVect& ref) const +{ + std::vector v; + int exist = this->queryarr(name, v); + AMREX_ALWAYS_ASSERT(v.size() == AMREX_SPACEDIM); + if (exist) { + for (int i = 0; i < AMREX_SPACEDIM; ++i) { ref[i] = v[i]; } + } + return exist; +} + +void +ParmParse::getarr (const char* name, RealVect& ref) const +{ + std::vector v; + this->getarr(name, v); + AMREX_ALWAYS_ASSERT(v.size() == AMREX_SPACEDIM); + for (int i = 0; i < AMREX_SPACEDIM; ++i) { ref[i] = v[i]; } +} + // // Return number of occurrences of parameter name. // From 20e6f2eadf0c297517588ba38973ec7c7084fa31 Mon Sep 17 00:00:00 2001 From: Weiqun Zhang Date: Sat, 27 Jul 2024 21:37:52 -0700 Subject: [PATCH 5/5] ParmParse: Fix assertion in new queryarr for IntVect & RealVect (#4051) For query functions, we should not assert the size unless the name actually exists. This fixes a bug in the new functions added in #4050. --- Src/Base/AMReX_ParmParse.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Src/Base/AMReX_ParmParse.cpp b/Src/Base/AMReX_ParmParse.cpp index 669485f40d6..7a1eae245d4 100644 --- a/Src/Base/AMReX_ParmParse.cpp +++ b/Src/Base/AMReX_ParmParse.cpp @@ -1774,8 +1774,8 @@ ParmParse::queryarr (const char* name, IntVect& ref) const { std::vector v; int exist = this->queryarr(name, v); - AMREX_ALWAYS_ASSERT(v.size() == AMREX_SPACEDIM); if (exist) { + AMREX_ALWAYS_ASSERT(v.size() == AMREX_SPACEDIM); for (int i = 0; i < AMREX_SPACEDIM; ++i) { ref[i] = v[i]; } } return exist; @@ -1795,8 +1795,8 @@ ParmParse::queryarr (const char* name, RealVect& ref) const { std::vector v; int exist = this->queryarr(name, v); - AMREX_ALWAYS_ASSERT(v.size() == AMREX_SPACEDIM); if (exist) { + AMREX_ALWAYS_ASSERT(v.size() == AMREX_SPACEDIM); for (int i = 0; i < AMREX_SPACEDIM; ++i) { ref[i] = v[i]; } } return exist;