introduce a helper class WelSegsSet

this wraps the set with the custom comparator. this is
just a internal helper class, does not need to be part of public API.
This commit is contained in:
Arne Morten Kvarving
2023-11-24 09:44:53 +01:00
parent 5a2d3b1f11
commit 01c1fda1c9
5 changed files with 149 additions and 42 deletions

View File

@@ -184,6 +184,7 @@ if(ENABLE_ECL_INPUT)
src/opm/input/eclipse/Schedule/MSW/Segment.cpp
src/opm/input/eclipse/Schedule/MSW/SegmentMatcher.cpp
src/opm/input/eclipse/Schedule/MSW/WellSegments.cpp
src/opm/input/eclipse/Schedule/MSW/WelSegsSet.cpp
src/opm/input/eclipse/Schedule/MSW/AICD.cpp
src/opm/input/eclipse/Schedule/MSW/SICD.cpp
src/opm/input/eclipse/Schedule/MSW/Valve.cpp

View File

@@ -43,6 +43,8 @@
#include <opm/input/eclipse/Schedule/WriteRestartFileEvents.hpp>
#include <opm/input/eclipse/Units/UnitSystem.hpp>
#include "src/opm/input/eclipse/Schedule/MSW/WelSegsSet.hpp"
namespace Opm
{
namespace Action {
@@ -76,6 +78,7 @@ namespace Opm
class WellMatcher;
enum class WellProducerCMode;
enum class WellStatus;
class WelSegsSet;
class WellTestConfig;
namespace RestartIO { struct RstState; }
@@ -132,28 +135,6 @@ namespace Opm
class Schedule {
public:
struct PairComp
{
bool operator()(const std::pair<std::string,KeywordLocation>& pair,
const std::string& str) const
{
return std::get<0>(pair) < str;
}
bool operator()(const std::pair<std::string,KeywordLocation>& pair1,
const std::pair<std::string,KeywordLocation>& pair2) const
{
return std::get<0>(pair1) < std::get<0>(pair2);
}
bool operator()(const std::string& str,
const std::pair<std::string,KeywordLocation>& pair) const
{
return str < std::get<0>(pair);
}
};
using WelSegsSet = std::set<std::pair<std::string,KeywordLocation>,PairComp>;
Schedule() = default;
explicit Schedule(std::shared_ptr<const Python> python_handle);
Schedule(const Deck& deck,
@@ -563,7 +544,7 @@ namespace Opm
void welsegs_handled(const std::string& well_name)
{
if (welsegs_wells)
welsegs_wells->insert({well_name, keyword.location()});
welsegs_wells->insert(well_name, keyword.location());
}
/// \brief Mark that the well occured in a COMPSEGS keyword

View File

@@ -0,0 +1,79 @@
/*
Copyright 2013 Statoil ASA.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include "WelSegsSet.hpp"
#include <opm/input/eclipse/Schedule/Well/Well.hpp>
#include <opm/input/eclipse/Schedule/Well/WellConnections.hpp>
#include <algorithm>
namespace Opm {
void WelSegsSet::insert(const std::string& well_name,
const KeywordLocation& location)
{
entries_.emplace(well_name, location);
}
std::vector<WelSegsSet::Entry>
WelSegsSet::difference(const std::set<std::string>& compsegs,
const std::vector<Well>& wells) const
{
std::vector<Entry> difference;
difference.reserve(entries_.size());
std::set_difference(entries_.begin(), entries_.end(),
compsegs.begin(), compsegs.end(),
std::back_inserter(difference),
PairComp());
// Ignore wells without connections
const auto empty_conn = [&wells](const Entry &x) {
return std::any_of(wells.begin(), wells.end(),
[wname = x.first](const Well& well)
{ return (well.name() == wname) && well.getConnections().empty(); });
};
difference.erase(std::remove_if(difference.begin(),
difference.end(), empty_conn),
difference.end());
return difference;
}
bool WelSegsSet::PairComp::
operator()(const Entry& pair, const std::string& str) const
{
return std::get<0>(pair) < str;
}
bool WelSegsSet::PairComp::
operator()(const Entry& pair1, const Entry& pair2) const
{
return std::get<0>(pair1) < std::get<0>(pair2);
}
bool WelSegsSet::PairComp::
operator()(const std::string& str, const Entry& pair) const
{
return str < std::get<0>(pair);
}
} // end namespace Opm

View File

@@ -0,0 +1,57 @@
/*
Copyright 2013 Statoil ASA.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef WEL_SEGS_SET_HPP
#define WEL_SEGS_SET_HPP
#include <opm/common/OpmLog/KeywordLocation.hpp>
#include <set>
#include <string>
#include <utility>
#include <vector>
namespace Opm {
class Well;
class WelSegsSet
{
public:
using Entry = std::pair<std::string,KeywordLocation>;
void insert(const std::string& well_name,
const KeywordLocation& location);
std::vector<Entry> difference(const std::set<std::string>& compsegs,
const std::vector<Well>& wells) const;
private:
struct PairComp
{
bool operator()(const Entry& pair, const std::string& str) const;
bool operator()(const Entry& pair1, const Entry& pair2) const;
bool operator()(const std::string& str, const Entry& pair) const;
};
std::set<Entry,PairComp> entries_;
};
} // end namespace Opm
#endif // WEL_SEGS_SET_HPP

View File

@@ -93,6 +93,7 @@
#include "Well/injection.hpp"
#include "MSW/Compsegs.hpp"
#include "MSW/WelSegsSet.hpp"
#include <algorithm>
#include <ctime>
@@ -521,34 +522,22 @@ namespace
/// \brief Check whether each MS well has COMPSEGS entry andissue error if not.
/// \param welsegs All wells with a WELSEGS entry together with the location.
/// \param compegs All wells with a COMPSEGS entry
void check_compsegs_consistency(::Opm::Schedule::WelSegsSet& welsegs,
std::set<std::string>& compsegs,
void check_compsegs_consistency(Opm::WelSegsSet& welsegs,
const std::set<std::string>& compsegs,
const std::vector<::Opm::Well>& wells)
{
std::vector<std::pair<std::string,::Opm::KeywordLocation>> difference;
difference.reserve(welsegs.size());
std::set_difference(welsegs.begin(), welsegs.end(),
compsegs.begin(), compsegs.end(),
std::back_inserter(difference),
::Opm::Schedule::PairComp());
// Ignore wells without connections
const auto empty_conn = [&wells](const std::pair<std::string,::Opm::KeywordLocation> &x) -> bool {
return std::any_of(wells.begin(), wells.end(),
[wname = x.first](const ::Opm::Well& well) {
return (well.name() == wname) && well.getConnections().empty(); }
);
};
difference.erase(std::remove_if(difference.begin(), difference.end(), empty_conn), difference.end());
const auto difference = welsegs.difference(compsegs, wells);
if (difference.size()) {
if (!difference.empty()) {
std::string well_str = "well";
if (difference.size()>1) {
if (difference.size() > 1) {
well_str.append("s");
}
well_str.append(":");
for(const auto& [name, location] : difference) {
well_str.append(fmt::format("\n {} in {} at line {}", name, location.filename, location.lineno));
well_str.append(fmt::format("\n {} in {} at line {}",
name, location.filename, location.lineno));
}
auto msg = fmt::format("Missing COMPSEGS keyword for the following multisegment {}.", well_str);
throw Opm::OpmInputError(msg, std::get<1>(difference[0]));