Normalise input data in UDQ definitions
The UDQDefine::input_string() function will return normalized input which is equivalent to the deck input string, but not necessarily identical. Normalizing which might give rise to differences: - All selectors/qualifiers in expressions like "WWCT '*'" are quoted. - Whether to pad operators with space like "170 + FU_PAR10" or "170+FU_PAR10" is hardcoded and independent of the space used in the input. - Floating point numbers is output with format "%g" - no trailing zeros.
This commit is contained in:
parent
f17b75ab53
commit
7939adf3e3
@ -21,10 +21,11 @@
|
||||
#ifndef UDQ_DEFINE_HPP
|
||||
#define UDQ_DEFINE_HPP
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQEnums.hpp>
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQSet.hpp>
|
||||
@ -101,7 +102,7 @@ private:
|
||||
KeywordLocation m_location;
|
||||
std::size_t m_report_step;
|
||||
UDQUpdate m_update_status;
|
||||
std::string string_data;
|
||||
mutable std::optional<std::string> string_data;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -187,6 +187,9 @@ namespace UDQ {
|
||||
bool scalarFunc(UDQTokenType token_type);
|
||||
bool cmpFunc(UDQTokenType token_type);
|
||||
bool setFunc(UDQTokenType token_type);
|
||||
bool trailingSpace(UDQTokenType token_type);
|
||||
bool leadingSpace(UDQTokenType token_type);
|
||||
|
||||
|
||||
std::string typeName(UDQVarType var_type);
|
||||
UDAKeyword keyword(UDAControl control);
|
||||
|
@ -198,12 +198,6 @@ UDQDefine::UDQDefine(const UDQParams& udq_params,
|
||||
}
|
||||
this->m_tokens = make_tokens(string_tokens);
|
||||
this->ast = std::make_shared<UDQASTNode>( UDQParser::parse(udq_params, this->m_var_type, this->m_keyword, this->m_location, this->m_tokens, parseContext, errors) );
|
||||
this->string_data = "";
|
||||
for (std::size_t index = 0; index < deck_data.size(); index++) {
|
||||
this->string_data += deck_data[index];
|
||||
if (index != deck_data.size() - 1)
|
||||
this->string_data += " ";
|
||||
}
|
||||
}
|
||||
|
||||
void UDQDefine::update_status(UDQUpdate update, std::size_t report_step) {
|
||||
@ -328,7 +322,33 @@ const std::string& UDQDefine::keyword() const {
|
||||
}
|
||||
|
||||
const std::string& UDQDefine::input_string() const {
|
||||
return this->string_data;
|
||||
if (!this->string_data.has_value()) {
|
||||
std::string s;
|
||||
/*
|
||||
A string representation equivalent to the input string is assembled by
|
||||
joining tokens and sprinkle with ' ' at semi random locations. The
|
||||
main use of this function is to output the definition string in form
|
||||
usable for the restart file.
|
||||
*/
|
||||
|
||||
for (std::size_t token_index = 0; token_index < this->m_tokens.size(); token_index++) {
|
||||
const auto& token = this->m_tokens[token_index];
|
||||
if (UDQ::leadingSpace(token.type()))
|
||||
s += " ";
|
||||
|
||||
s += token.str();
|
||||
if (token_index == (this->m_tokens.size() - 1))
|
||||
continue;
|
||||
|
||||
if (UDQ::trailingSpace(token.type())) {
|
||||
s += " ";
|
||||
continue;
|
||||
}
|
||||
}
|
||||
this->string_data = s;
|
||||
|
||||
}
|
||||
return this->string_data.value();
|
||||
}
|
||||
|
||||
std::set<UDQTokenType> UDQDefine::func_tokens() const {
|
||||
|
@ -372,6 +372,26 @@ std::string typeName(UDQVarType var_type) {
|
||||
}
|
||||
}
|
||||
|
||||
bool trailingSpace(UDQTokenType token_type) {
|
||||
if (binaryFunc(token_type))
|
||||
return true;
|
||||
|
||||
if (cmpFunc(token_type))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool leadingSpace(UDQTokenType token_type) {
|
||||
if (binaryFunc(token_type))
|
||||
return true;
|
||||
|
||||
if (cmpFunc(token_type))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace {
|
||||
template <typename Value>
|
||||
Value lookup_control_map_value(const std::map<UDAControl, Value>& map, const UDAControl control)
|
||||
|
@ -16,12 +16,21 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OPM. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <fmt/format.h>
|
||||
#include <numeric>
|
||||
|
||||
#include <opm/parser/eclipse/EclipseState/Schedule/UDQ/UDQToken.hpp>
|
||||
|
||||
namespace Opm {
|
||||
|
||||
namespace {
|
||||
std::string format_double(double d) {
|
||||
return fmt::format("{:g}", d);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
UDQToken::UDQToken(const std::string& string_token, UDQTokenType token_type_) :
|
||||
token_type(token_type_)
|
||||
{
|
||||
@ -56,10 +65,13 @@ std::string UDQToken::str() const {
|
||||
if (this->m_selector.empty())
|
||||
return std::get<std::string>(this->m_value);
|
||||
|
||||
return std::get<std::string>(this->m_value) + std::string{" "} + std::accumulate(this->m_selector.begin(), this->m_selector.end(), std::string{},
|
||||
[](const std::string& s1, const std::string& s2) { return s1 + " " + s2; });
|
||||
std::string quoted_selector;
|
||||
for (const auto& s : this->m_selector)
|
||||
quoted_selector += " '" + s + "'";
|
||||
|
||||
return std::get<std::string>(this->m_value) + quoted_selector;
|
||||
} else
|
||||
return std::to_string(std::get<double>(this->m_value));
|
||||
return format_double(std::get<double>(this->m_value));
|
||||
}
|
||||
|
||||
|
||||
|
@ -1272,10 +1272,10 @@ BOOST_AUTO_TEST_CASE(UDQPARSE_TEST1) {
|
||||
KeywordLocation location;
|
||||
UDQParams udqp;
|
||||
UDQDefine def1(udqp, "WUBHP",0, location, {"1/(WWCT", "'W1*')"});
|
||||
BOOST_CHECK_EQUAL( def1.input_string() , "1/(WWCT 'W1*')");
|
||||
BOOST_CHECK_EQUAL( def1.input_string() , "1 / (WWCT 'W1*')");
|
||||
|
||||
UDQDefine def2(udqp, "WUBHP",0, location, {"2*(1", "+" , "WBHP)"});
|
||||
BOOST_CHECK_EQUAL( def2.input_string() , "2*(1 + WBHP)");
|
||||
UDQDefine def2(udqp, "WUBHP",0, location, {"2 * (1", "+" , "WBHP)"});
|
||||
BOOST_CHECK_EQUAL( def2.input_string() , "2 * (1 + WBHP)");
|
||||
}
|
||||
|
||||
|
||||
|
@ -646,22 +646,22 @@ BOOST_AUTO_TEST_CASE (Declared_UDQ_data)
|
||||
const auto& zUdl = udqData.getZUDL();
|
||||
|
||||
auto start = 0*udqDims[5];
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 0].c_str() , "(WOPR PR"); // udq NO. 1
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 1].c_str() , "OD1 - 17"); // udq NO. 1
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 2].c_str() , "0) * 0.6"); // udq NO. 1
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 3].c_str() , "0 "); // udq NO. 1
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 0].c_str() , "(WOPR 'P"); // udq NO. 1
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 1].c_str() , "ROD1' - "); // udq NO. 1
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 2].c_str() , "170) * 0"); // udq NO. 1
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 3].c_str() , ".6 "); // udq NO. 1
|
||||
|
||||
start = 3*udqDims[5];
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 0].c_str() , "(GOPR GR"); // udq NO. 1
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 1].c_str() , "P1 - 449"); // udq NO. 1
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 2].c_str() , ") * 0.77"); // udq NO. 1
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 3].c_str() , " "); // udq NO. 1
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 0].c_str() , "(GOPR 'G"); // udq NO. 1
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 1].c_str() , "RP1' - 4"); // udq NO. 1
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 2].c_str() , "49) * 0."); // udq NO. 1
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 3].c_str() , "77 "); // udq NO. 1
|
||||
|
||||
start = 4*udqDims[5];
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 0].c_str() , "(WLPR PR"); // udq NO. 1
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 1].c_str() , "OD2 - 30"); // udq NO. 1
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 2].c_str() , "0) * 0.8"); // udq NO. 1
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 3].c_str() , "0 "); // udq NO. 1
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 0].c_str() , "(WLPR 'P"); // udq NO. 1
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 1].c_str() , "ROD2' - "); // udq NO. 1
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 2].c_str() , "300) * 0"); // udq NO. 1
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 3].c_str() , ".8 "); // udq NO. 1
|
||||
|
||||
start = 5*udqDims[5];
|
||||
BOOST_CHECK_EQUAL(zUdl[start + 0].c_str() , "(FLPR - "); // udq NO. 1
|
||||
@ -761,9 +761,6 @@ BOOST_AUTO_TEST_CASE (Declared_UDQ_data)
|
||||
}
|
||||
|
||||
|
||||
BOOST_CHECK_EQUAL(rst_state.udqs[0].expression(), "(WOPR PROD1 - 170) * 0.60");
|
||||
|
||||
|
||||
const auto& udq_params = es.runspec().udqParams();
|
||||
const auto& input_config = sched[1].udq();
|
||||
Opm::UDQConfig rst_config(udq_params, rst_state);
|
||||
@ -779,7 +776,6 @@ BOOST_AUTO_TEST_CASE (Declared_UDQ_data)
|
||||
rst_udq_state.load_rst(rst_state);
|
||||
for (const auto& input_def : input_config.definitions()) {
|
||||
const auto& rst_def = rst_config.define( input_def.keyword() );
|
||||
|
||||
auto input_eval = input_def.eval(input_context);
|
||||
auto rst_eval = rst_def.eval(rst_context);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user