diff options
author | 2020-05-02 01:30:01 +0200 | |
---|---|---|
committer | 2020-05-01 16:30:01 -0700 | |
commit | ed8fdc9ca97aa51c522549c565dda4123c679eba (patch) | |
tree | f5346dfe7efc4439bede1f92b29090ebe15c25df /Source/Utils/IntervalsParser.cpp | |
parent | 96a59e58c57814bc3e0eed73f8c8919bd6c48620 (diff) | |
download | WarpX-ed8fdc9ca97aa51c522549c565dda4123c679eba.tar.gz WarpX-ed8fdc9ca97aa51c522549c565dda4123c679eba.tar.zst WarpX-ed8fdc9ca97aa51c522549c565dda4123c679eba.zip |
Add parser for more general intervals (slices) (#925)
* Add parser for slices and split function
* Apply suggestions from code review
Co-Authored-By: MaxThevenet <mthevenet@lbl.gov>
* Moved new classes to a separate file
* Add intervals parser to input parameter documentation
* Fix syntax in parameters.rst
* Update Source/Utils/IntervalsParser.cpp
* Apply suggestions from code review
Co-Authored-By: Axel Huebl <axel.huebl@plasma.ninja>
* Implement intervals parser for load balancing
* remove EOL whitespace
* Remove unnecessary sentence in parameters doc
Co-authored-by: MaxThevenet <mthevenet@lbl.gov>
Co-authored-by: Axel Huebl <axel.huebl@plasma.ninja>
Diffstat (limited to 'Source/Utils/IntervalsParser.cpp')
-rw-r--r-- | Source/Utils/IntervalsParser.cpp | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/Source/Utils/IntervalsParser.cpp b/Source/Utils/IntervalsParser.cpp new file mode 100644 index 000000000..657911524 --- /dev/null +++ b/Source/Utils/IntervalsParser.cpp @@ -0,0 +1,111 @@ +#include "WarpXUtil.H" +#include "IntervalsParser.H" + +SliceParser::SliceParser (const std::string& instr) +{ + const std::string assert_msg = "ERROR: '" + instr + "' is not a valid syntax for a slice."; + + // split string and trim whitespaces + auto insplit = WarpXUtilStr::split<std::vector<std::string>>(instr, m_separator, true); + + if(insplit.size() == 1){ // no colon in input string. The input is the period. + WarpXUtilMsg::AlwaysAssert(amrex::is_it<int>(insplit[0], m_period),assert_msg);} + else if(insplit.size() == 2) // 1 colon in input string. The input is start:stop + { + if (!insplit[0].empty()){ + WarpXUtilMsg::AlwaysAssert(amrex::is_it<int>(insplit[0], m_start),assert_msg);} + if (!insplit[1].empty()){ + WarpXUtilMsg::AlwaysAssert(amrex::is_it<int>(insplit[1], m_stop),assert_msg);} + } + else // 2 colons in input string. The input is start:stop:period + { + WarpXUtilMsg::AlwaysAssert(insplit.size() == 3,assert_msg); + if (!insplit[0].empty()){ + WarpXUtilMsg::AlwaysAssert(amrex::is_it<int>(insplit[0], m_start),assert_msg);} + if (!insplit[1].empty()){ + WarpXUtilMsg::AlwaysAssert(amrex::is_it<int>(insplit[1], m_stop),assert_msg);} + if (!insplit[2].empty()){ + WarpXUtilMsg::AlwaysAssert(amrex::is_it<int>(insplit[2], m_period),assert_msg);} + } +} + +bool SliceParser::contains (const int n) const +{ + if (m_period <= 0) {return false;} + return (n - m_start) % m_period == 0 && n >= m_start && n <= m_stop; +} + +int SliceParser::nextContains (const int n) const +{ + if (m_period <= 0) {return std::numeric_limits<int>::max();} + int next = m_start; + if (n >= m_start) {next = ((n-m_start)/m_period + 1)*m_period+m_start;} + if (next > m_stop) {next = std::numeric_limits<int>::max();} + return next; +} + +int SliceParser::previousContains (const int n) const +{ + if (m_period <= 0) {return false;} + int previous = ((std::min(n-1,m_stop)-m_start)/m_period)*m_period+m_start; + if ((n < m_start) || (previous < 0)) {previous = 0;} + return previous; +} + +int SliceParser::getPeriod () const {return m_period;} + +int SliceParser::getStart () const {return m_start;} + +int SliceParser::getStop () const {return m_stop;} + +IntervalsParser::IntervalsParser (const std::string& instr) +{ + auto insplit = WarpXUtilStr::split<std::vector<std::string>>(instr, m_separator); + + for(int i=0; i<insplit.size(); i++) + { + SliceParser temp_slice(insplit[i]); + m_slices.push_back(temp_slice); + if ((temp_slice.getPeriod() > 0) && + (temp_slice.getStop() >= temp_slice.getStart())) m_activated = true; + } +} + +bool IntervalsParser::contains (const int n) const +{ + for(int i=0; i<m_slices.size(); i++){ + if (m_slices[i].contains(n)) return true; + } + return false; +} + +int IntervalsParser::nextContains (const int n) const +{ + int next = std::numeric_limits<int>::max(); + for(int i=0; i<m_slices.size(); i++){ + next = std::min(m_slices[i].nextContains(n),next); + } + return next; +} + +int IntervalsParser::previousContains (const int n) const +{ + int previous = 0; + for(int i=0; i<m_slices.size(); i++){ + previous = std::max(m_slices[i].previousContains(n),previous); + } + return previous; +} + +int IntervalsParser::previousContainsInclusive (const int n) const +{ + if (contains(n)){return n;} + else {return previousContains(n);} +} + +int IntervalsParser::localPeriod (const int n) const +{ + return nextContains(n) - previousContainsInclusive(n); +} + +bool IntervalsParser::isActivated () const {return m_activated;} |