DynamicState.hpp
Go to the documentation of this file.
1/*
2 Copyright 2013 Statoil 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
21#ifndef DYNAMICSTATE_HPP_
22#define DYNAMICSTATE_HPP_
23
24#include <stdexcept>
25#include <vector>
26#include <algorithm>
27#include <utility>
28
30
31
32namespace Opm {
33
57template< class T >
59 friend class Schedule;
60 public:
61 typedef typename std::vector< T >::iterator iterator;
62
63 DynamicState() = default;
64
65 DynamicState( const TimeMap& timeMap, T initial ) :
66 m_data( timeMap.size(), initial ),
67 initial_range( timeMap.size() )
68 {}
69
70 DynamicState(const std::vector<T>& data,
71 size_t init_range) :
72 m_data(data), initial_range(init_range)
73 {}
74
75 void globalReset( T value ) {
76 this->m_data.assign( this->m_data.size(), value );
77 }
78
79 const T& back() const {
80 return m_data.back();
81 }
82
83 const T& at( size_t index ) const {
84 return this->m_data.at( index );
85 }
86
87 const T& operator[](size_t index) const {
88 return this->at( index );
89 }
90
91 const T& get(size_t index) const {
92 return this->at( index );
93 }
94
95 void updateInitial( T initial ) {
96 std::fill_n( this->m_data.begin(), this->initial_range, initial );
97 }
98
99
100 std::vector<std::pair<std::size_t, T>> unique() const {
101 if (this->m_data.empty())
102 return {};
103
104 const auto * current_value = std::addressof(this->m_data[0]);
105 std::size_t current_index = 0;
106 std::vector<std::pair<std::size_t, T>> result{{current_index, *current_value}};
107 while (true) {
108 if (this->m_data[current_index] != *current_value) {
109 current_value = std::addressof(this->m_data[current_index]);
110 result.emplace_back(current_index, *current_value);
111 }
112
113 current_index++;
114 if (current_index == this->m_data.size())
115 break;
116 }
117
118 return result;
119 }
120
121 bool is_new_data(size_t index) const {
122 return index == 0 || (at(index) != at(index - 1));
123 }
124
129 bool update( size_t index, T value ) {
130 if( this->initial_range == this->m_data.size() )
131 this->initial_range = index;
132
133 const bool change = (value != this->m_data.at( index ));
134
135 if( !change ) return false;
136
137 std::fill( this->m_data.begin() + index,
138 this->m_data.end(),
139 value );
140
141 return true;
142 }
143
144 void update_elm( size_t index, const T& value ) {
145 if (this->m_data.size() <= index)
146 throw std::out_of_range("Invalid index for update_elm()");
147
148 this->m_data[index] = value;
149 }
150
151
152 /*
153 Will assign all currently equal values starting at index with the new
154 value. Purpose of the method is to support manipulations of an existing
155 Schedule object, if e.g. a well is initially closed in the interval
156 [T1,T2] and then opened at time T1 < Tx < T2 then the open should be
157 applied for all times in the range [Tx,T2].
158 */
159 void update_equal(size_t index, const T& value) {
160 if (this->m_data.size() <= index)
161 throw std::out_of_range("Invalid index for update_equal()");
162
163 const T prev_value = this->m_data[index];
164 if (prev_value == value)
165 return;
166
167 while (true) {
168 if (this->m_data[index] != prev_value)
169 break;
170
171 this->m_data[index] = value;
172
173 index++;
174 if (index == this->m_data.size())
175 break;
176
177 }
178 }
179
182 int find(const T& value) const {
183 auto iter = std::find( m_data.begin() , m_data.end() , value);
184 if( iter == this->m_data.end() ) return -1;
185
186 return std::distance( m_data.begin() , iter );
187 }
188
189 template<typename P>
190 int find_if(P&& pred) const {
191 auto iter = std::find_if(m_data.begin(), m_data.end(), std::forward<P>(pred));
192 if( iter == this->m_data.end() ) return -1;
193
194 return std::distance( m_data.begin() , iter );
195 }
196
199 int find_not(const T& value) const {
200 auto iter = std::find_if_not( m_data.begin() , m_data.end() , [&value] (const T& elm) { return value == elm; });
201 if( iter == this->m_data.end() ) return -1;
202
203 return std::distance( m_data.begin() , iter );
204 }
205
207 return this->m_data.begin();
208 }
209
210
212 return this->m_data.end();
213 }
214
215
216 std::size_t size() const {
217 return this->m_data.size();
218 }
219
220 const std::vector<T>& data() const {
221 return m_data;
222 }
223
224 size_t initialRange() const {
225 return initial_range;
226 }
227
228 bool operator==(const DynamicState<T>& data) const {
229 return m_data == data.m_data &&
230 initial_range == data.initial_range;
231 }
232
233 // complexType=true if contained type has a serializeOp
234 template<class Serializer, bool complexType = true>
235 void serializeOp(Serializer& serializer)
236 {
237 std::vector<T> unique;
238 auto indices = split(unique);
239 serializer.template vector<T,complexType>(unique);
240 serializer(indices);
241 if (!serializer.isSerializing())
242 reconstruct(unique, indices);
243 }
244
245 private:
246 std::vector< T > m_data;
247 size_t initial_range;
248
249 std::vector<size_t> split(std::vector<T>& unique) const {
250 std::vector<size_t> idxVec;
251 idxVec.reserve(m_data.size() + 1);
252 for (const auto& w : m_data) {
253 auto candidate = std::find(unique.begin(), unique.end(), w);
254 size_t idx = candidate - unique.begin();
255 if (candidate == unique.end()) {
256 unique.push_back(w);
257 idx = unique.size() - 1;
258 }
259 idxVec.push_back(idx);
260 }
261 idxVec.push_back(initial_range);
262
263 return idxVec;
264 }
265
266 void reconstruct(const std::vector<T>& unique,
267 const std::vector<size_t>& idxVec) {
268 m_data.clear();
269 m_data.reserve(idxVec.size() - 1);
270 for (size_t i = 0; i < idxVec.size() - 1; ++i)
271 m_data.push_back(unique[idxVec[i]]);
272
273 initial_range = idxVec.back();
274 }
275};
276
277}
278
279#endif
280
int index
Definition: cJSON.h:168
Definition: DynamicState.hpp:58
const T & get(size_t index) const
Definition: DynamicState.hpp:91
std::size_t size() const
Definition: DynamicState.hpp:216
const T & at(size_t index) const
Definition: DynamicState.hpp:83
iterator end()
Definition: DynamicState.hpp:211
const T & back() const
Definition: DynamicState.hpp:79
int find(const T &value) const
Definition: DynamicState.hpp:182
bool update(size_t index, T value)
Definition: DynamicState.hpp:129
iterator begin()
Definition: DynamicState.hpp:206
size_t initialRange() const
Definition: DynamicState.hpp:224
const std::vector< T > & data() const
Definition: DynamicState.hpp:220
int find_if(P &&pred) const
Definition: DynamicState.hpp:190
DynamicState(const TimeMap &timeMap, T initial)
Definition: DynamicState.hpp:65
void update_equal(size_t index, const T &value)
Definition: DynamicState.hpp:159
DynamicState(const std::vector< T > &data, size_t init_range)
Definition: DynamicState.hpp:70
void serializeOp(Serializer &serializer)
Definition: DynamicState.hpp:235
std::vector< std::pair< std::size_t, T > > unique() const
Definition: DynamicState.hpp:100
int find_not(const T &value) const
Definition: DynamicState.hpp:199
void update_elm(size_t index, const T &value)
Definition: DynamicState.hpp:144
bool operator==(const DynamicState< T > &data) const
Definition: DynamicState.hpp:228
DynamicState()=default
bool is_new_data(size_t index) const
Definition: DynamicState.hpp:121
void updateInitial(T initial)
Definition: DynamicState.hpp:95
std::vector< T >::iterator iterator
Definition: DynamicState.hpp:61
void globalReset(T value)
Definition: DynamicState.hpp:75
const T & operator[](size_t index) const
Definition: DynamicState.hpp:87
Definition: Schedule.hpp:113
Definition: Serializer.hpp:38
Definition: TimeMap.hpp:40
Definition: A.hpp:4
T value(details::expression_node< T > *n)
Definition: exprtk.hpp:12955