Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add necessary templating to support float in simulators #4016

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion msim/src/msim.cpp
Expand Up @@ -136,7 +136,8 @@ void msim::post_step(data::Solution& /* sol */,
for (const auto& action : actions.pending(this->action_state, std::chrono::system_clock::to_time_t(sim_time))) {
auto result = action->eval(context);
if (result) {
this->schedule.applyAction(report_step, *action, result.wells(), {});
this->schedule.applyAction(report_step, *action, result.wells(),
std::unordered_map<std::string,double>{});
}
}

Expand Down
21 changes: 19 additions & 2 deletions opm/input/eclipse/Schedule/Schedule.cpp
Expand Up @@ -739,7 +739,8 @@ void Schedule::iterateScheduleSection(std::size_t load_start, std::size_t load_e
DeckKeyword action_keyword(parserKeyword);
action_keyword.addRecord(std::move(deckRecord));
action.addKeyword(action_keyword);
SimulatorUpdate delta = this->applyAction(report_step, action, {} /*matching_wells*/, {}/*target_wellpi*/);
SimulatorUpdate delta = this->applyAction(report_step, action, {} /*matching_wells*/,
std::unordered_map<std::string,double>{}/*target_wellpi*/);
this->simUpdateFromPython->append(delta);
}

Expand Down Expand Up @@ -1468,6 +1469,21 @@ File {} line {}.)", pattern, location.keyword, location.filename, location.linen
}


SimulatorUpdate
Schedule::applyAction(std::size_t reportStep,
const Action::ActionX& action,
const std::vector<std::string>& matching_wells,
const std::unordered_map<std::string, float>& target_wellpi)
{
std::unordered_map<std::string, double> dtarget_wellpi;
for (const auto& w : target_wellpi) {
dtarget_wellpi.emplace(w.first, w.second);
}

return this->applyAction(reportStep, action, matching_wells, dtarget_wellpi);
}


SimulatorUpdate
Schedule::applyAction(std::size_t reportStep,
const Action::ActionX& action,
Expand Down Expand Up @@ -1559,7 +1575,8 @@ File {} line {}.)", pattern, location.keyword, location.filename, location.linen
OpmLog::error(fmt::format("Tried to apply action: {} on non existing well: {}", action_name, wname));
}

return this->applyAction(reportStep, action, well_names, {});
return this->applyAction(reportStep, action, well_names,
std::unordered_map<std::string,double>{});
} else {
OpmLog::error(fmt::format("Tried to apply action unknown action: {}", action_name));
return {};
Expand Down
10 changes: 9 additions & 1 deletion opm/input/eclipse/Schedule/Schedule.hpp
Expand Up @@ -241,7 +241,15 @@ namespace Opm
updating internal datastructures after the ACTIONX keywords have been
applied.
*/
SimulatorUpdate applyAction(std::size_t reportStep, const Action::ActionX& action, const std::vector<std::string>& matching_wells, const std::unordered_map<std::string, double>& wellpi);
SimulatorUpdate applyAction(std::size_t reportStep,
const Action::ActionX& action,
const std::vector<std::string>& matching_wells,
const std::unordered_map<std::string, double>& wellpi);

SimulatorUpdate applyAction(std::size_t reportStep,
const Action::ActionX& action,
const std::vector<std::string>& matching_wells,
const std::unordered_map<std::string, float>& wellpi);
/*
The runPyAction() will run the Python script in a PYACTION keyword. In
the case of Schedule updates the recommended way of doing that from
Expand Down
15 changes: 10 additions & 5 deletions opm/input/eclipse/Schedule/Well/PAvgCalculator.cpp
Expand Up @@ -1208,10 +1208,15 @@ linearCombination(const Scalar alpha, typename PAvgCalculator<Scalar>::Result
return x;
}

template class PAvgCalculator<double>;
template PAvgCalculator<double>::Result linearCombination(const double,
PAvgCalculator<double>::Result,
const double,
const PAvgCalculator<double>::Result&);
#define INSTANCE_TYPE(T) \
template class PAvgCalculator<T>; \
template PAvgCalculator<T>::Result \
linearCombination(const T, \
PAvgCalculator<T>::Result, \
const T, \
const PAvgCalculator<T>::Result&);

INSTANCE_TYPE(double)
INSTANCE_TYPE(float)

} // namespace Opm
Expand Up @@ -126,5 +126,6 @@ allWBPCells() const
}

template class PAvgCalculatorCollection<double>;
template class PAvgCalculatorCollection<float>;

} // namespace Opm
1 change: 1 addition & 0 deletions opm/input/eclipse/Schedule/Well/PAvgDynamicSourceData.cpp
Expand Up @@ -115,3 +115,4 @@ index(const std::size_t source) const
}

template class Opm::PAvgDynamicSourceData<double>;
template class Opm::PAvgDynamicSourceData<float>;
4 changes: 2 additions & 2 deletions opm/material/common/UniformXTabulated2DFunction.hpp
Expand Up @@ -417,14 +417,14 @@ class UniformXTabulated2DFunction
{
if (xPos_.empty() || xPos_.back() < nextX) {
xPos_.push_back(nextX);
yPos_.push_back(-1e100);
yPos_.push_back(-1e30);
samples_.push_back({});
return xPos_.size() - 1;
}
else if (xPos_.front() > nextX) {
// this is slow, but so what?
xPos_.insert(xPos_.begin(), nextX);
yPos_.insert(yPos_.begin(), -1e100);
yPos_.insert(yPos_.begin(), -1e30);
samples_.insert(samples_.begin(), std::vector<SamplePoint>());
return 0;
}
Expand Down
14 changes: 14 additions & 0 deletions opm/output/data/Solution.cpp
Expand Up @@ -64,6 +64,20 @@ Solution::insert(std::string name,
}


std::pair<Solution::iterator, bool>
Solution::insert(std::string name,
const UnitSystem::measure m,
std::vector<float> xs,
const TargetType type)
{
std::vector<double> xsd(xs.size());
std::copy(xs.begin(), xs.end(), xsd.begin());
return this->emplace(std::piecewise_construct,
std::forward_as_tuple(std::move(name)),
std::forward_as_tuple(m, std::move(xsd), type));
}


std::pair<Solution::iterator, bool>
Solution::insert(std::string name,
std::vector<int> xs,
Expand Down
5 changes: 5 additions & 0 deletions opm/output/data/Solution.hpp
Expand Up @@ -58,6 +58,11 @@ class Solution : public std::map<std::string, data::CellData>
std::vector<double>,
TargetType );

std::pair<iterator, bool> insert(std::string name,
UnitSystem::measure,
std::vector<float>,
TargetType );

std::pair<iterator, bool> insert(std::string name,
std::vector<int>,
TargetType );
Expand Down
12 changes: 12 additions & 0 deletions opm/output/eclipse/RestartValue.cpp
Expand Up @@ -96,6 +96,18 @@ namespace Opm {
this->addExtra(key, UnitSystem::measure::identity, std::move(data));
}

void RestartValue::addExtra(const std::string& key, std::vector<float> data) {
std::vector<double> ddata(data.size());
std::copy(data.begin(), data.end(), ddata.begin());
this->addExtra(key, UnitSystem::measure::identity, std::move(ddata));
}

void RestartValue::addExtra(const std::string& key, UnitSystem::measure dimension, std::vector<float> data) {
std::vector<double> ddata(data.size());
std::copy(data.begin(), data.end(), ddata.begin());
this->addExtra(key, dimension, std::move(ddata));
}

void RestartValue::convertFromSI(const UnitSystem& units) {
this->solution.convertFromSI(units);
for (auto & extra_value : this->extra) {
Expand Down
2 changes: 2 additions & 0 deletions opm/output/eclipse/RestartValue.hpp
Expand Up @@ -90,7 +90,9 @@ namespace Opm {

bool hasExtra(const std::string& key) const;
void addExtra(const std::string& key, UnitSystem::measure dimension, std::vector<double> data);
void addExtra(const std::string& key, UnitSystem::measure dimension, std::vector<float> data);
void addExtra(const std::string& key, std::vector<double> data);
void addExtra(const std::string& key, std::vector<float> data);
const std::vector<double>& getExtra(const std::string& key) const;

void convertFromSI(const UnitSystem& units);
Expand Down
24 changes: 16 additions & 8 deletions tests/parser/ACTIONX.cpp
Expand Up @@ -223,7 +223,8 @@ TSTEP

Action::Result action_result(true);
const auto& action1 = sched[0].actions.get()["ACTION"];
auto sim_update = sched.applyAction(0, action1, action_result.wells(), {});
auto sim_update = sched.applyAction(0, action1, action_result.wells(),
std::unordered_map<std::string,double>{});
const auto& affected_wells = sim_update.affected_wells;
std::vector<std::string> expected_wells{"W0", "W1", "W3"};
BOOST_CHECK( std::is_permutation(affected_wells.begin(), affected_wells.end(),
Expand Down Expand Up @@ -289,7 +290,8 @@ COMPDAT
Schedule sched = make_schedule(TRAILING_COMPDAT);
Action::Result action_result(true);
const auto& action1 = sched[0].actions.get()["ACTION"];
BOOST_CHECK_NO_THROW( sched.applyAction(0, action1, {}, {}));
BOOST_CHECK_NO_THROW( sched.applyAction(0, action1, {},
std::unordered_map<std::string,double>{}));
}

BOOST_AUTO_TEST_CASE(EMPTY) {
Expand Down Expand Up @@ -1186,7 +1188,8 @@ TSTEP


Action::Result action_result(true);
sched.applyAction(0, action1, action_result.wells(), {});
sched.applyAction(0, action1, action_result.wells(),
std::unordered_map<std::string,double>{});

{
const auto& group = sched.getGroup("G1", 1);
Expand Down Expand Up @@ -1305,7 +1308,8 @@ TSTEP


Action::Result action_result(true);
const auto& sim_update = sched.applyAction(0, action1, action_result.wells(), {});
const auto& sim_update = sched.applyAction(0, action1, action_result.wells(),
std::unordered_map<std::string,double>{});
BOOST_CHECK( sim_update.affected_wells.empty() );
{
const auto& glo = sched.glo(0);
Expand Down Expand Up @@ -1379,7 +1383,8 @@ TSTEP
BOOST_CHECK(!sched.hasWell("PROD1"));

Action::Result action_result(true);
sched.applyAction(0, action1, action_result.wells(), {});
sched.applyAction(0, action1, action_result.wells(),
std::unordered_map<std::string,double>{});

const auto& well = sched.getWell("PROD1", 1);
const auto& connections = well.getConnections();
Expand Down Expand Up @@ -1439,10 +1444,12 @@ TSTEP


Action::Result action_result(true);
BOOST_CHECK_THROW( sched.applyAction(0, action1, action_result.wells(), {}), std::exception);
BOOST_CHECK_THROW( sched.applyAction(0, action1, action_result.wells(),
std::unordered_map<std::string,double>{}), std::exception);
{
const auto& well = sched.getWell("PROD1", 0);
const auto& sim_update = sched.applyAction(0, action1, action_result.wells(), {{"PROD1", well.convertDeckPI(500)}});
const auto& sim_update = sched.applyAction(0, action1, action_result.wells(),
std::unordered_map<std::string,double>{{"PROD1", well.convertDeckPI(500)}});
BOOST_CHECK_EQUAL( sim_update.affected_wells.count("PROD1"), 1);
BOOST_CHECK_EQUAL( sim_update.affected_wells.size(), 1);
}
Expand Down Expand Up @@ -1512,7 +1519,8 @@ TSTEP
BOOST_CHECK(sched[0].geo_keywords().empty());

Action::Result action_result(true);
auto sim_update = sched.applyAction(0, action1, action_result.wells(), {});
auto sim_update = sched.applyAction(0, action1, action_result.wells(),
std::unordered_map<std::string,double>{});
BOOST_CHECK( sim_update.tran_update );
BOOST_CHECK_EQUAL(sched[0].geo_keywords().size(), 3);
}
Expand Down
20 changes: 10 additions & 10 deletions tests/test_Restart.cpp
Expand Up @@ -238,10 +238,10 @@ data::Solution mkSolution(int numCells)
fun::iota rvi( 400.0, 400.0 + numCells );

sol.insert("RS", measure::identity,
{ rsi.begin(), rsi.end() },
std::vector<double>{ rsi.begin(), rsi.end() },
data::TargetType::RESTART_SOLUTION);
sol.insert("RV", measure::identity,
{ rvi.begin(), rvi.end() },
std::vector<double>{ rvi.begin(), rvi.end() },
data::TargetType::RESTART_SOLUTION);

return sol;
Expand Down Expand Up @@ -571,7 +571,7 @@ BOOST_AUTO_TEST_CASE(ECL_FORMATTED) {
RestartValue restart_value(cells, wells, groups, {});

io_config.setEclCompatibleRST( false );
restart_value.addExtra("EXTRA", UnitSystem::measure::pressure, {10,1,2,3});
restart_value.addExtra("EXTRA", UnitSystem::measure::pressure, std::vector<double>{10.0,1.0,2.0,3.0});

const auto outputDir = test_area.currentWorkingDirectory();

Expand Down Expand Up @@ -736,17 +736,17 @@ BOOST_AUTO_TEST_CASE(ExtraData_KEYS) {
auto groups = mkGroups();
RestartValue restart_value(cells, wells, groups, {});

BOOST_CHECK_THROW( restart_value.addExtra("TOO-LONG-KEY", {0,1,2}), std::runtime_error);
BOOST_CHECK_THROW( restart_value.addExtra("TOO-LONG-KEY", std::vector{0.0,1.0,2.0}), std::runtime_error);

// Keys must be unique
restart_value.addExtra("KEY", {0,1,1});
BOOST_CHECK_THROW( restart_value.addExtra("KEY", {0,1,1}), std::runtime_error);
restart_value.addExtra("KEY", std::vector{0.0,1.0,1.0});
BOOST_CHECK_THROW( restart_value.addExtra("KEY", std::vector{0.0,1.0,1.0}), std::runtime_error);

/* The keys must be unique across solution and extra_data */
BOOST_CHECK_THROW( restart_value.addExtra("PRESSURE", {0,1}), std::runtime_error);
BOOST_CHECK_THROW( restart_value.addExtra("PRESSURE", std::vector{0.0,1.0}), std::runtime_error);

/* Must avoid using reserved keys like 'LOGIHEAD' */
BOOST_CHECK_THROW( restart_value.addExtra("LOGIHEAD", {0,1}), std::runtime_error);
BOOST_CHECK_THROW( restart_value.addExtra("LOGIHEAD", std::vector{0.0,1.0}), std::runtime_error);
}

BOOST_AUTO_TEST_CASE(ExtraData_content) {
Expand All @@ -771,7 +771,7 @@ BOOST_AUTO_TEST_CASE(ExtraData_content) {
SummaryState st(TimeService::now(), 0.0);
const auto sumState = sim_state(setup.schedule);

restart_value.addExtra("EXTRA", UnitSystem::measure::pressure, {10,1,2,3});
restart_value.addExtra("EXTRA", UnitSystem::measure::pressure, std::vector<double>{10.0,1.0,2.0,3.0});

const auto outputDir = test_area.currentWorkingDirectory();

Expand Down Expand Up @@ -865,7 +865,7 @@ BOOST_AUTO_TEST_CASE(STORE_THPRES) {
setup.schedule), std::runtime_error);
*/

restart_value.addExtra("THRESHPR", UnitSystem::measure::pressure, {0,1});
restart_value.addExtra("THRESHPR", UnitSystem::measure::pressure, std::vector<double>{0.0,1.0});
const auto sumState = sim_state(base_setup.schedule);
Action::State action_state;
UDQState udq_state(99);
Expand Down