/* Copyright 2020 Equinor AS. 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 . */ #ifndef FIELD_DATA_HPP #define FIELD_DATA_HPP #include #include #include #include #include #include #include #include #include namespace Opm { namespace Fieldprops { template static void compress(std::vector& data, const std::vector& active_map) { std::size_t shift = 0; for (std::size_t g = 0; g < active_map.size(); g++) { if (active_map[g] && shift > 0) { data[g - shift] = data[g]; continue; } if (!active_map[g]) shift += 1; } data.resize(data.size() - shift); } template struct FieldData { std::vector data; std::vector value_status; keywords::keyword_info kw_info; std::optional> global_data; std::optional> global_value_status; mutable bool all_set; FieldData() = default; FieldData(const keywords::keyword_info& info, std::size_t active_size, std::size_t global_size) : data(std::vector(active_size)), value_status(active_size, value::status::uninitialized), kw_info(info), all_set(false) { if (global_size != 0) { this->global_data = std::vector(global_size); this->global_value_status = std::vector(global_size, value::status::uninitialized); } if (info.scalar_init) this->default_assign( *info.scalar_init ); } std::size_t size() const { return this->data.size(); } bool valid() const { if (this->all_set) return true; static const std::array invalid_value = {value::status::uninitialized, value::status::empty_default}; const auto& it = std::find_first_of(this->value_status.begin(), this->value_status.end(), invalid_value.begin(), invalid_value.end()); this->all_set = (it == this->value_status.end()); return this->all_set; } void compress(const std::vector& active_map) { Fieldprops::compress(this->data, active_map); Fieldprops::compress(this->value_status, active_map); } void copy(const FieldData& src, const std::vector& index_list) { for (const auto& ci : index_list) { this->data[ci.active_index] = src.data[ci.active_index]; this->value_status[ci.active_index] = src.value_status[ci.active_index]; } } void default_assign(T value) { std::fill(this->data.begin(), this->data.end(), value); std::fill(this->value_status.begin(), this->value_status.end(), value::status::valid_default); if (this->global_data) { std::fill(this->global_data->begin(), this->global_data->end(), value); std::fill(this->global_value_status->begin(), this->global_value_status->end(), value::status::valid_default); } } void default_assign(const std::vector& src) { if (src.size() != this->size()) throw std::invalid_argument("Size mismatch got: " + std::to_string(src.size()) + " expected: " + std::to_string(this->size())); std::copy(src.begin(), src.end(), this->data.begin()); std::fill(this->value_status.begin(), this->value_status.end(), value::status::valid_default); } void default_update(const std::vector& src) { if (src.size() != this->size()) throw std::invalid_argument("Size mismatch got: " + std::to_string(src.size()) + " expected: " + std::to_string(this->size())); for (std::size_t i = 0; i < src.size(); i++) { if (!value::has_value(this->value_status[i])) { this->value_status[i] = value::status::valid_default; this->data[i] = src[i]; } } } void update(std::size_t index, T value, value::status status) { this->data[index] = value; this->value_status[index] = status; } }; } // end namespace Fieldprops } // end namespace Opm #endif // FIELD_DATA_HPP