My Project
Loading...
Searching...
No Matches
FieldData.hpp
1/*
2 Copyright 2020 Equinor AS.
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 FIELD_DATA_HPP
21#define FIELD_DATA_HPP
22
23#include <opm/input/eclipse/EclipseState/Grid/Box.hpp>
24#include <opm/input/eclipse/EclipseState/Grid/Keywords.hpp>
25
26#include <opm/input/eclipse/Deck/value_status.hpp>
27
28#include <algorithm>
29#include <array>
30#include <cstddef>
31#include <functional>
32#include <optional>
33#include <stdexcept>
34#include <string>
35#include <vector>
36
37namespace Opm {
38 class KeywordLocation;
39} // namespace Opm
40
41namespace Opm::Fieldprops {
42
43 template <typename T>
44 static void compress(std::vector<T>& data,
45 const std::vector<bool>& active_map,
46 const std::size_t values_per_cell = 1)
47 {
48 const std::size_t num_cells = active_map.size();
49 if (data.size() != num_cells * values_per_cell) {
50 throw std::invalid_argument("Data size does not match the size of active_map times values_per_cell.");
51 }
52
53 std::size_t shift = 0;
54 for (std::size_t value_index = 0; value_index < values_per_cell; ++value_index) {
55 for (std::size_t g = 0; g < active_map.size(); ++g) {
56 if (active_map[g] && shift > 0) {
57 const std::size_t orig_index = value_index * num_cells + g;
58 data[orig_index - shift] = data[orig_index];
59 continue;
60 }
61 if (!active_map[g]) {
62 shift += 1;
63 }
64 }
65 }
66
67 data.resize(data.size() - shift);
68 }
69
70 template <typename T>
71 struct FieldData
72 {
73 std::vector<T> data{};
74 std::vector<value::status> value_status{};
76 std::optional<std::vector<T>> global_data{};
77 std::optional<std::vector<value::status>> global_value_status{std::nullopt};
78 mutable bool all_set{false};
79
80 bool operator==(const FieldData& other) const
81 {
82 return this->data == other.data &&
83 this->value_status == other.value_status &&
84 this->kw_info == other.kw_info &&
85 this->global_data == other.global_data &&
86 this->global_value_status == other.global_value_status;
87 }
88
89 FieldData() = default;
90
92 const std::size_t active_size,
93 const std::size_t global_size)
94 : data (active_size * info.num_value)
95 , value_status(active_size * info.num_value, value::status::uninitialized)
96 , kw_info (info)
97 , all_set (false)
98 {
99 if (global_size != 0) {
100 this->global_data.emplace(global_size * this->numValuePerCell());
101 this->global_value_status.emplace(global_size * this->numValuePerCell(), value::status::uninitialized);
102 }
103
104 if (info.scalar_init) {
105 this->default_assign(*info.scalar_init);
106 }
107 }
108
109 std::size_t numCells() const
110 {
111 return this->data.size() / this->numValuePerCell();
112 }
113
114 std::size_t dataSize() const
115 {
116 return this->data.size();
117 }
118
119 std::size_t numValuePerCell() const
120 {
121 return this->kw_info.num_value;
122 }
123
124 bool valid() const
125 {
126 if (this->all_set) {
127 return true;
128 }
129
130 // Object is "valid" if the 'value_status' of every element is
131 // neither uninitialised nor empty.
132 return this->all_set =
133 std::none_of(this->value_status.begin(), this->value_status.end(),
134 [](const value::status& status)
135 {
136 return (status == value::status::uninitialized)
137 || (status == value::status::empty_default);
138 });
139 }
140
141 bool valid_default() const
142 {
143 return std::all_of(this->value_status.begin(), this->value_status.end(),
144 [](const value::status& status)
145 {
146 return status == value::status::valid_default;
147 });
148 }
149
150 void compress(const std::vector<bool>& active_map)
151 {
152 Fieldprops::compress(this->data, active_map, this->numValuePerCell());
153 Fieldprops::compress(this->value_status, active_map, this->numValuePerCell());
154 }
155
156 void checkInitialisedCopy(const FieldData& src,
157 const std::vector<Box::cell_index>& index_list,
158 const std::string& from,
159 const std::string& to,
160 const KeywordLocation& loc,
161 const bool global = false);
162
163 void default_assign(T value)
164 {
165 std::fill(this->data.begin(), this->data.end(), value);
166 std::fill(this->value_status.begin(),
167 this->value_status.end(),
168 value::status::valid_default);
169
170 if (this->global_data) {
171 std::fill(this->global_data->begin(),
172 this->global_data->end(), value);
173
174 std::fill(this->global_value_status->begin(),
175 this->global_value_status->end(),
176 value::status::valid_default);
177 }
178 }
179
180 void default_assign(const std::vector<T>& src)
181 {
182 if (src.size() != this->dataSize()) {
183 throw std::invalid_argument {
184 "Size mismatch got: " + std::to_string(src.size()) +
185 ", expected: " + std::to_string(this->dataSize())
186 };
187 }
188
189 std::copy(src.begin(), src.end(), this->data.begin());
190 std::fill(this->value_status.begin(), this->value_status.end(),
191 value::status::valid_default);
192 }
193
194 void default_assign_global(const std::vector<T>& src)
195 {
196 if (!global_data) {
197 throw std::invalid_argument {
198 "Cannot call default_assign_global on keyword with local storage"
199 };
200 }
201
202 if (src.size() != this->global_data->size()) {
203 throw std::invalid_argument {
204 "Size mismatch got: " + std::to_string(src.size()) +
205 ", expected: " + std::to_string(this->dataSize())
206 };
207 }
208
209 std::copy(src.begin(), src.end(), this->global_data->begin());
210 std::fill(this->global_value_status->begin(), this->global_value_status->end(),
211 value::status::valid_default);
212 }
213
214 void update_local_from_global(std::function<std::size_t(std::size_t)> local_to_global)
215 {
216 if (!global_data) {
217 throw std::invalid_argument {
218 "Cannot call update_local_from_gloabl on keyword with local storage"
219 };
220 }
221 std::size_t i{};
222 auto current_status = this->value_status.begin();
223 for(auto current = this->data.begin(); current != this->data.end(); ++current, ++current_status, ++i)
224 {
225 const auto& global = local_to_global(i);
226 *current = (*global_data)[global];
227 *current_status = (*global_value_status)[global];
228 }
229 }
230
231 void default_update(const std::vector<T>& src)
232 {
233 if (src.size() != this->dataSize()) {
234 throw std::invalid_argument {
235 "Size mismatch got: " + std::to_string(src.size()) +
236 ", expected: " + std::to_string(this->dataSize())
237 };
238 }
239
240 for (std::size_t i = 0; i < src.size(); ++i) {
241 if (!value::has_value(this->value_status[i])) {
242 this->value_status[i] = value::status::valid_default;
243 this->data[i] = src[i];
244 }
245 }
246 }
247
248 void update(const std::size_t index,
249 T value,
250 const value::status status)
251 {
252 this->data[index] = value;
253 this->value_status[index] = status;
254 }
255 };
256
257} // namespace Opm::Fieldprops
258
259#endif // FIELD_DATA_HPP
Definition KeywordLocation.hpp:27
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition Exceptions.hpp:30
Definition FieldData.hpp:72
Definition Keywords.hpp:31