WellContainer.hpp
Go to the documentation of this file.
1/*
2 Copyright 2021 Equinor ASA
3
4 This file is part of the Open Porous Media project (OPM).
5
6 OPM is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 OPM is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with OPM. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20#ifndef OPM_WELL_CONTAINER_HEADER_INCLUDED
21#define OPM_WELL_CONTAINER_HEADER_INCLUDED
22
23#include <initializer_list>
24#include <optional>
25#include <stdexcept>
26#include <string>
27#include <unordered_map>
28#include <vector>
29
30namespace Opm {
31
32
33/*
34 The WellContainer<T> class is a small utility class designed to manage the
35 dynamic state of per well quantities, like active control and phase rates. The
36 values are stored continously in a vector, but they are added with a name, and
37 can also be accessed and updated with the name.
38
39 The class is created to facilitate safe and piecewise refactoring of the
40 WellState class, and might have a short life in the
41 development timeline.
42*/
43
44
45template <class T>
47public:
48 WellContainer() = default;
49
50 WellContainer(std::initializer_list<std::pair<std::string,T>> init_list) {
51 for (const auto& [name, value] : init_list)
52 this->add(name, value);
53 }
54
56 {
57 WellContainer<T> result;
58
59 result.m_data = {data};
60 result.index_map = {{"test1", 1}, {"test2", 4}};
61
62 return result;
63 }
64
65 bool empty() const {
66 return this->index_map.empty();
67 }
68
69 std::size_t size() const {
70 return this->m_data.size();
71 }
72
73 T& add(const std::string& name, T&& value) {
74 if (index_map.count(name) != 0)
75 throw std::logic_error("An object with name: " + name + " already exists in container");
76
77 this->index_map.emplace(name, this->m_data.size());
78 this->m_data.push_back(std::forward<T>(value));
79 return this->m_data.back();
80 }
81
82 T& add(const std::string& name, const T& value) {
83 if (index_map.count(name) != 0)
84 throw std::logic_error("An object with name: " + name + " already exists in container");
85
86 this->index_map.emplace(name, this->m_data.size());
87 this->m_data.push_back(value);
88 return this->m_data.back();
89 }
90
91 bool has(const std::string& name) const {
92 return (index_map.count(name) != 0);
93 }
94
95 /*
96 Will copy the value from other to this - for all wells which are present
97 in both containers.
98 */
99 void copy_welldata(const WellContainer<T>& other) {
100 if (this->index_map == other.index_map)
101 this->m_data = other.m_data;
102 else {
103 for (const auto& [name, index] : this->index_map)
104 this->update_if(index, name, other);
105 }
106 }
107
108 /*
109 Will copy the value for well @name from other to this. The well @name must
110 exist in both containers, otherwise an exception is thrown.
111 */
112 void copy_welldata(const WellContainer<T>& other, const std::string& name) {
113 auto this_index = this->index_map.at(name);
114 auto other_index = other.index_map.at(name);
115 this->m_data[this_index] = other.m_data[other_index];
116 }
117
118 T& operator[](std::size_t index) {
119 return this->m_data.at(index);
120 }
121
122 const T& operator[](std::size_t index) const {
123 return this->m_data.at(index);
124 }
125
126 T& operator[](const std::string& name) {
127 auto index = this->index_map.at(name);
128 return this->m_data[index];
129 }
130
131 const T& operator[](const std::string& name) const {
132 auto index = this->index_map.at(name);
133 return this->m_data[index];
134 }
135
136 void clear() {
137 this->m_data.clear();
138 this->index_map.clear();
139 }
140
141 typename std::vector<T>::const_iterator begin() const {
142 return this->m_data.begin();
143 }
144
145 typename std::vector<T>::const_iterator end() const {
146 return this->m_data.end();
147 }
148
149 const std::vector<T>& data() const {
150 return this->m_data;
151 }
152
153 std::optional<int> well_index(const std::string& wname) const {
154 auto index_iter = this->index_map.find(wname);
155 if (index_iter != this->index_map.end())
156 return index_iter->second;
157
158 return std::nullopt;
159 }
160
161 const std::string& well_name(std::size_t well_index) const {
162 for (const auto& [wname, windex] : this->index_map) {
163 if (windex == well_index)
164 return wname;
165 }
166 throw std::logic_error("No such well");
167 }
168
169 std::vector<std::string> wells() const {
170 std::vector<std::string> wlist;
171 for (const auto& [wname, _] : this->index_map) {
172 (void)_;
173 wlist.push_back(wname);
174 }
175 return wlist;
176 }
177
178 template<class Serializer>
179 void serializeOp(Serializer& serializer)
180 {
181 serializer(m_data);
182 serializer(index_map);
183 }
184
185 bool operator==(const WellContainer<T>& rhs) const
186 {
187 return this->m_data == rhs.m_data &&
188 this->index_map == rhs.index_map;
189 }
190
191private:
192 void update_if(std::size_t index, const std::string& name, const WellContainer<T>& other) {
193 auto other_iter = other.index_map.find(name);
194 if (other_iter == other.index_map.end())
195 return;
196
197 auto other_index = other_iter->second;
198 this->m_data[index] = other.m_data[other_index];
199 }
200
201
202 std::vector<T> m_data;
203 std::unordered_map<std::string, std::size_t> index_map;
204};
205
206
207}
208
209
210#endif
Definition: WellContainer.hpp:46
std::vector< std::string > wells() const
Definition: WellContainer.hpp:169
T & operator[](const std::string &name)
Definition: WellContainer.hpp:126
T & add(const std::string &name, const T &value)
Definition: WellContainer.hpp:82
bool empty() const
Definition: WellContainer.hpp:65
static WellContainer serializationTestObject(const T &data)
Definition: WellContainer.hpp:55
void copy_welldata(const WellContainer< T > &other)
Definition: WellContainer.hpp:99
const std::vector< T > & data() const
Definition: WellContainer.hpp:149
void clear()
Definition: WellContainer.hpp:136
bool has(const std::string &name) const
Definition: WellContainer.hpp:91
void copy_welldata(const WellContainer< T > &other, const std::string &name)
Definition: WellContainer.hpp:112
const T & operator[](const std::string &name) const
Definition: WellContainer.hpp:131
T & add(const std::string &name, T &&value)
Definition: WellContainer.hpp:73
std::vector< T >::const_iterator end() const
Definition: WellContainer.hpp:145
bool operator==(const WellContainer< T > &rhs) const
Definition: WellContainer.hpp:185
std::size_t size() const
Definition: WellContainer.hpp:69
const T & operator[](std::size_t index) const
Definition: WellContainer.hpp:122
const std::string & well_name(std::size_t well_index) const
Definition: WellContainer.hpp:161
WellContainer()=default
T & operator[](std::size_t index)
Definition: WellContainer.hpp:118
WellContainer(std::initializer_list< std::pair< std::string, T > > init_list)
Definition: WellContainer.hpp:50
void serializeOp(Serializer &serializer)
Definition: WellContainer.hpp:179
std::optional< int > well_index(const std::string &wname) const
Definition: WellContainer.hpp:153
std::vector< T >::const_iterator begin() const
Definition: WellContainer.hpp:141
Definition: BlackoilPhases.hpp:27