From 2e94003ad78b674d46cc255920576374f96021cf Mon Sep 17 00:00:00 2001 From: Einar Baumann Date: Tue, 4 Dec 2018 13:58:04 +0100 Subject: [PATCH 1/6] Appended .SMSPEC to summary path. When running with a Singularity container, FieldOpt ERT is unable to find the summary file unless it has .SMSPEC explicitly appended to the path. This commit fixes said issue. Also, error messages are no longer truncated. --- FieldOpt/Simulation/simulator_interfaces/ix_simulator.cpp | 2 +- FieldOpt/Utilities/printer.hpp | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/FieldOpt/Simulation/simulator_interfaces/ix_simulator.cpp b/FieldOpt/Simulation/simulator_interfaces/ix_simulator.cpp index 3d2f063b4..657db3fc4 100644 --- a/FieldOpt/Simulation/simulator_interfaces/ix_simulator.cpp +++ b/FieldOpt/Simulation/simulator_interfaces/ix_simulator.cpp @@ -71,7 +71,7 @@ bool IXSimulator::Evaluate(int timeout, int threads) { if (success) { if (VERB_SIM >= 1) { Printer::info("Simulation successful. Reading results."); } results_->DumpResults(); - results_->ReadResults(QString::fromStdString(paths_.GetPath(Paths::SIM_WORK_DIR)) + "/SUMMARYVECS"); + results_->ReadResults(QString::fromStdString(paths_.GetPath(Paths::SIM_WORK_DIR)) + "/SUMMARYVECS.SMSPEC"); } else { if (VERB_SIM >= 1) { Printer::info("Simulation failed."); } diff --git a/FieldOpt/Utilities/printer.hpp b/FieldOpt/Utilities/printer.hpp index b0bb7ee2a..6b0ef260c 100644 --- a/FieldOpt/Utilities/printer.hpp +++ b/FieldOpt/Utilities/printer.hpp @@ -182,7 +182,6 @@ inline void error(const std::string &text) { std::stringstream ss; ss << FLRED; std::string content = text; - truncate_text(content, 59); pad_text(content, 59); ss << "╔═════════════════════════════════════════════════════════════════════╗" << "\n"; ss << "║ ERROR: " << content << " ║" << "\n"; From f6785f2f753be374709b686eaa4306f41e80e8bd Mon Sep 17 00:00:00 2001 From: Einar Baumann Date: Tue, 4 Dec 2018 15:34:11 +0100 Subject: [PATCH 2/6] Append SMSPEC to summary path for non-timeout evaluate (used for base case) --- FieldOpt/Simulation/simulator_interfaces/ix_simulator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FieldOpt/Simulation/simulator_interfaces/ix_simulator.cpp b/FieldOpt/Simulation/simulator_interfaces/ix_simulator.cpp index 657db3fc4..a65a67861 100644 --- a/FieldOpt/Simulation/simulator_interfaces/ix_simulator.cpp +++ b/FieldOpt/Simulation/simulator_interfaces/ix_simulator.cpp @@ -50,7 +50,7 @@ void IXSimulator::Evaluate() { script_args_ ); if (VERB_SIM >= 1) { Printer::info("Unmonitored simulation done. Reading results."); } - results_->ReadResults(QString::fromStdString(paths_.GetPath(Paths::SIM_WORK_DIR)) + "/SUMMARYVECS"); + results_->ReadResults(QString::fromStdString(paths_.GetPath(Paths::SIM_WORK_DIR)) + "/SUMMARYVECS.SMSPEC"); updateResultsInModel(); } bool IXSimulator::Evaluate(int timeout, int threads) { From afd3a43a2f191554213b23e0dc991a61e3437164 Mon Sep 17 00:00:00 2001 From: Einar Baumann Date: Thu, 6 Dec 2018 13:48:35 +0100 Subject: [PATCH 3/6] Add more flexibiliti to summary search path. IX will for some decks prepend DECK_NAME_ before the summary name (e.g. DECK_NAME_SUMMARYVECS.UNSMR). FieldOpt will now check for this and use whichever it finds first. I neither is found, an error will be printed and FieldOpt will exit. --- .../simulator_interfaces/ix_simulator.cpp | 25 ++++++++++++++++--- .../simulator_interfaces/ix_simulator.h | 2 ++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/FieldOpt/Simulation/simulator_interfaces/ix_simulator.cpp b/FieldOpt/Simulation/simulator_interfaces/ix_simulator.cpp index a65a67861..732ee50cc 100644 --- a/FieldOpt/Simulation/simulator_interfaces/ix_simulator.cpp +++ b/FieldOpt/Simulation/simulator_interfaces/ix_simulator.cpp @@ -37,6 +37,7 @@ IXSimulator::IXSimulator(Settings::Settings *settings, Model::Model *model) } deck_name_ = driver_file_name_.split(".afi").first(); results_ = new Results::ECLResults(); + result_path_ = ""; } void IXSimulator::Evaluate() { copyDriverFiles(); @@ -50,7 +51,7 @@ void IXSimulator::Evaluate() { script_args_ ); if (VERB_SIM >= 1) { Printer::info("Unmonitored simulation done. Reading results."); } - results_->ReadResults(QString::fromStdString(paths_.GetPath(Paths::SIM_WORK_DIR)) + "/SUMMARYVECS.SMSPEC"); + results_->ReadResults(QString::fromStdString(paths_.GetPath(Paths::SIM_WORK_DIR)) + "/SECTOR_ICV_OPTIMIZATION_20181205_SUMMARYVECS.SMSPEC"); updateResultsInModel(); } bool IXSimulator::Evaluate(int timeout, int threads) { @@ -69,9 +70,12 @@ bool IXSimulator::Evaluate(int timeout, int threads) { QString::fromStdString(paths_.GetPath(Paths::SIM_EXEC_SCRIPT_FILE)), script_args_, t); if (success) { - if (VERB_SIM >= 1) { Printer::info("Simulation successful. Reading results."); } results_->DumpResults(); - results_->ReadResults(QString::fromStdString(paths_.GetPath(Paths::SIM_WORK_DIR)) + "/SUMMARYVECS.SMSPEC"); + if (result_path_.size() == 0) { + setResultPath(); + } + if (VERB_SIM >= 1) { Printer::info("Simulation successful. Reading results from " + result_path_.toStdString()); } + results_->ReadResults(result_path_); } else { if (VERB_SIM >= 1) { Printer::info("Simulation failed."); } @@ -129,5 +133,20 @@ void IXSimulator::copyDriverFiles() { "Simulation", "IXSimulator"); } } +void IXSimulator::setResultPath() { + QString result_dir = QString::fromStdString(paths_.GetPath(Paths::SIM_WORK_DIR)); + QString result_name; + if (FileExists(result_dir + "/SUMMARYVECS.SMSPEC")) { + result_name = "/SUMMARYVECS.SMSPEC"; + } + else if ( FileExists(result_dir + "/" + deck_name_ + "_SUMMARYVECS.SMSPEC")) { + result_name = "/" + deck_name_ + "_SUMMARYVECS.SMSPEC"; + } + else { + Printer::error("Unable to find summary file. Aborting."); + exit(1); + } + result_path_ = result_dir + result_name; +} } diff --git a/FieldOpt/Simulation/simulator_interfaces/ix_simulator.h b/FieldOpt/Simulation/simulator_interfaces/ix_simulator.h index e6936e9e6..abefa7f54 100644 --- a/FieldOpt/Simulation/simulator_interfaces/ix_simulator.h +++ b/FieldOpt/Simulation/simulator_interfaces/ix_simulator.h @@ -38,8 +38,10 @@ class IXSimulator : public Simulator { void UpdateFilePaths() override; private: void copyDriverFiles(); + void setResultPath(); QString deck_name_; + QString result_path_; }; From cef461d010c6a4bb7484231a5c8cbf785de1fcda Mon Sep 17 00:00:00 2001 From: Einar Baumann Date: Fri, 7 Dec 2018 14:18:11 +0100 Subject: [PATCH 4/6] Use safe getters for field properties. This fixes the issue with ERT crashing when attempting to get values for a non-existent timestep 0 --- FieldOpt/ERTWrapper/eclsummaryreader.cpp | 27 ++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/FieldOpt/ERTWrapper/eclsummaryreader.cpp b/FieldOpt/ERTWrapper/eclsummaryreader.cpp index 2e7d42602..3dcfbb069 100644 --- a/FieldOpt/ERTWrapper/eclsummaryreader.cpp +++ b/FieldOpt/ERTWrapper/eclsummaryreader.cpp @@ -158,7 +158,7 @@ void ECLSummaryReader::initializeTimeVector() { for (int i = 0; i < double_vector_size(time); ++i) { time_[i] = (double_vector_safe_iget(time, i)); } - time_[0] = 0; // For some reason this is often not 0, but something > 1e8. Probably the time since epoch. + time_[0] = GetFirstReportStep(); double_vector_free(time); } @@ -318,8 +318,11 @@ void ECLSummaryReader::initializeFieldCumulatives() { fopt_ = std::vector(time_.size(), 0.0); if (hasFieldVar("FOPT")) { + int fopt_index = ecl_smspec_get_field_var_params_index(smspec, "FOPT"); + double_vector_type * fopt = ecl_sum_alloc_data_vector(ecl_sum_, fopt_index, true); + assert(double_vector_size(fopt) == time_.size()); for (int i = 0; i < time_.size(); ++i) { - fopt_[i] = ecl_sum_get_field_var_from_sim_days(ecl_sum_, time_[i], "FOPT"); + fopt_[i] = double_vector_safe_iget(fopt, i); } fopt_[0] = 0.0; } @@ -334,8 +337,11 @@ void ECLSummaryReader::initializeFieldCumulatives() { fwpt_ = std::vector(time_.size(), 0.0); if (hasFieldVar("FWPT")) { + int fwpt_index = ecl_smspec_get_field_var_params_index(smspec, "FWPT"); + double_vector_type * fwpt = ecl_sum_alloc_data_vector(ecl_sum_, fwpt_index, true); + assert(double_vector_size(fwpt) == time_.size()); for (int i = 0; i < time_.size(); ++i) { - fwpt_[i] = ecl_sum_get_field_var_from_sim_days(ecl_sum_, time_[i], "FWPT"); + fwpt_[i] = double_vector_safe_iget(fwpt, i); } fwpt_[0] = 0.0; } @@ -350,8 +356,11 @@ void ECLSummaryReader::initializeFieldCumulatives() { fgpt_ = std::vector(time_.size(), 0.0); if (hasFieldVar("FGPT")) { + int fgpt_index = ecl_smspec_get_field_var_params_index(smspec, "FGPT"); + double_vector_type * fgpt = ecl_sum_alloc_data_vector(ecl_sum_, fgpt_index, true); + assert(double_vector_size(fgpt) == time_.size()); for (int i = 0; i < time_.size(); ++i) { - fgpt_[i] = ecl_sum_get_field_var_from_sim_days(ecl_sum_, time_[i], "FGPT"); + fgpt_[i] = double_vector_safe_iget(fgpt, i); } fgpt_[0] = 0.0; } @@ -366,8 +375,11 @@ void ECLSummaryReader::initializeFieldCumulatives() { fwit_ = std::vector(time_.size(), 0.0); if (hasFieldVar("FWIT")) { + int fwit_index = ecl_smspec_get_field_var_params_index(smspec, "FWIT"); + double_vector_type * fwit = ecl_sum_alloc_data_vector(ecl_sum_, fwit_index, true); + assert(double_vector_size(fwit) == time_.size()); for (int i = 0; i < time_.size(); ++i) { - fwit_[i] = ecl_sum_get_field_var_from_sim_days(ecl_sum_, time_[i], "FWIT"); + fwit_[i] = double_vector_safe_iget(fwit, i); } fwit_[0] = 0.0; } @@ -382,8 +394,11 @@ void ECLSummaryReader::initializeFieldCumulatives() { fgit_ = std::vector(time_.size(), 0.0); if (hasFieldVar("FGIT")) { + int fgit_index = ecl_smspec_get_field_var_params_index(smspec, "FGIT"); + double_vector_type * fgit = ecl_sum_alloc_data_vector(ecl_sum_, fgit_index, true); + assert(double_vector_size(fgit) == time_.size()); for (int i = 0; i < time_.size(); ++i) { - fgit_[i] = ecl_sum_get_field_var_from_sim_days(ecl_sum_, time_[i], "FGIT"); + fgit_[i] = double_vector_safe_iget(fgit, i); } fgit_[0] = 0.0; } From 4579fba89d65ed26a0cb3d8268c4dd229aa2dcc1 Mon Sep 17 00:00:00 2001 From: Einar Baumann Date: Fri, 7 Dec 2018 14:18:58 +0100 Subject: [PATCH 5/6] Skip time step if it's more than one year prior to the next time step. This enables calculation of NPV for restart simulations --- FieldOpt/Optimization/objective/NPV.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/FieldOpt/Optimization/objective/NPV.cpp b/FieldOpt/Optimization/objective/NPV.cpp index eca5b62d7..1e379103f 100644 --- a/FieldOpt/Optimization/objective/NPV.cpp +++ b/FieldOpt/Optimization/objective/NPV.cpp @@ -74,6 +74,13 @@ double NPV::value() const { double discount_factor; int j = 1; for (int i = 0; i < report_times.size(); i++) { + if (i < report_times.size() - 1 && (report_times[i+1] - report_times[i]) > 365) { + std::stringstream ss; + ss << "Skipping assumed pre-simulation time step " << report_times[i] + << ". Next time step: " << report_times[i+1] << ". Ignore if this is time 0 in a restart case."; + Printer::ext_warn(ss.str(), "Optimization", "NPV"); + continue; + } if (std::fmod(report_times.at(i), 365) == 0) { discount_factor = 1 / (1 * (pow(1 + components_->at(k)->discount, j - 1))); discount_factor_list->append(discount_factor); From a754dfccdfd030374f171832599dd522e57f5b9a Mon Sep 17 00:00:00 2001 From: Einar Baumann Date: Mon, 10 Dec 2018 14:29:44 +0100 Subject: [PATCH 6/6] Use new method of finding summary path in both Evaluate implementations --- .../Simulation/simulator_interfaces/ix_simulator.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/FieldOpt/Simulation/simulator_interfaces/ix_simulator.cpp b/FieldOpt/Simulation/simulator_interfaces/ix_simulator.cpp index 732ee50cc..2fdb07a7d 100644 --- a/FieldOpt/Simulation/simulator_interfaces/ix_simulator.cpp +++ b/FieldOpt/Simulation/simulator_interfaces/ix_simulator.cpp @@ -50,8 +50,12 @@ void IXSimulator::Evaluate() { QString::fromStdString(paths_.GetPath(Paths::SIM_EXEC_SCRIPT_FILE)), script_args_ ); - if (VERB_SIM >= 1) { Printer::info("Unmonitored simulation done. Reading results."); } - results_->ReadResults(QString::fromStdString(paths_.GetPath(Paths::SIM_WORK_DIR)) + "/SECTOR_ICV_OPTIMIZATION_20181205_SUMMARYVECS.SMSPEC"); + results_->DumpResults(); + if (result_path_.size() == 0) { + setResultPath(); + } + if (VERB_SIM >= 1) { Printer::info("Unmonitored simulation done. Reading results from " + result_path_.toStdString()); } + results_->ReadResults(result_path_); updateResultsInModel(); } bool IXSimulator::Evaluate(int timeout, int threads) { @@ -136,10 +140,11 @@ void IXSimulator::copyDriverFiles() { void IXSimulator::setResultPath() { QString result_dir = QString::fromStdString(paths_.GetPath(Paths::SIM_WORK_DIR)); QString result_name; + if (VERB_SIM >= 2) Printer::ext_info("Setting simulator result path.", "Simulation", "IXSimulator"); if (FileExists(result_dir + "/SUMMARYVECS.SMSPEC")) { result_name = "/SUMMARYVECS.SMSPEC"; } - else if ( FileExists(result_dir + "/" + deck_name_ + "_SUMMARYVECS.SMSPEC")) { + else if (FileExists(result_dir + "/" + deck_name_ + "_SUMMARYVECS.SMSPEC")) { result_name = "/" + deck_name_ + "_SUMMARYVECS.SMSPEC"; } else { @@ -147,6 +152,7 @@ void IXSimulator::setResultPath() { exit(1); } result_path_ = result_dir + result_name; + if (VERB_SIM >= 2) Printer::ext_info("Set simulator result path to " + result_path_.toStdString(), "Simulation", "IXSimulator"); } }