EclKW.hpp
Go to the documentation of this file.
1/*
2 Copyright 2015 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_ERT_ECL_KW
21#define OPM_ERT_ECL_KW
22
23#include <string>
24#include <memory>
25#include <vector>
26#include <stdexcept>
27#include <type_traits>
28
30#include <ert/ecl/ecl_kw.hpp>
31#include <ert/ecl/ecl_type.hpp>
32#include <ert/ecl/FortIO.hpp>
33
34namespace ERT {
35 template< typename > struct ecl_type {};
36
37 template<> struct ecl_type< float >
38 { static const ecl_type_enum type { ECL_FLOAT_TYPE }; };
39
40 template<> struct ecl_type< double >
41 { static const ecl_type_enum type { ECL_DOUBLE_TYPE }; };
42
43 template<> struct ecl_type< int >
44 { static const ecl_type_enum type { ECL_INT_TYPE }; };
45
46 template<> struct ecl_type<bool>
47 { static const ecl_type_enum type {ECL_BOOL_TYPE}; };
48
49 template<> struct ecl_type< char* >
50 { static const ecl_type_enum type { ECL_CHAR_TYPE }; };
51
52 template<> struct ecl_type< const char* >
53 { static const ecl_type_enum type { ECL_CHAR_TYPE }; };
54
55 /*
56 Both std::string and char* are mapped to the eight character string type
57 ECL_CHAR_TYPE. That implies that the variable length string type
58 ECL_STRING is invisible from this API.
59 */
60
61 template<> struct ecl_type< std::string >
62 { static const ecl_type_enum type { ECL_CHAR_TYPE}; };
63
64 template<> struct ecl_type<const std::string>
65 { static const ecl_type_enum type {ECL_CHAR_TYPE}; };
66
67 template <typename T>
68 class EclKW_ref {
69 public:
70 explicit EclKW_ref( ecl_kw_type* kw ) : m_kw( kw ) {
72 throw std::invalid_argument("Type error");
73 }
74
75 EclKW_ref() noexcept = default;
76
77 const char* name() const {
78 return ecl_kw_get_header( this->m_kw );
79 }
80
81 size_t size() const {
82 return size_t( ecl_kw_get_size( this->m_kw ) );
83 }
84
85 void fwrite(FortIO& fortio) const {
86 ecl_kw_fwrite( this->m_kw , fortio.get() );
87 }
88
89 T at( size_t i ) const {
90 return *static_cast< T* >( ecl_kw_iget_ptr( this->m_kw, i ) );
91 }
92
93 T& operator[](size_t i) {
94 return *static_cast< T* >( ecl_kw_iget_ptr( this->m_kw, i ) );
95 }
96
97 const typename std::remove_pointer< T >::type* data() const {
98 using Tp = const typename std::remove_pointer< T >::type*;
99 return static_cast< Tp >( ecl_kw_get_ptr( this->m_kw ) );
100 }
101
102 ecl_kw_type* get() const {
103 return this->m_kw;
104 }
105
106 void resize(size_t new_size) {
107 ecl_kw_resize( this->m_kw , new_size );
108 }
109
110 protected:
111 ecl_kw_type* m_kw = nullptr;
112 };
113
114template<>
115inline bool EclKW_ref< bool >::at( size_t i ) const {
116 return ecl_kw_iget_bool( this->m_kw, i );
117}
118
119
120template<>
121inline const char* EclKW_ref< const char* >::at( size_t i ) const {
122 return ecl_kw_iget_char_ptr( this->m_kw, i );
123}
124
125
126template<>
128 return ecl_kw_iget_char_ptr( this->m_kw, i );
129}
130
131
132
133/*
134 The current implementation of "string" and "bool" storage in the underlying C
135 ecl_kw structure does not lend itself to easily implement operator[]. We have
136 therefore explicitly deleted them here.
137*/
138
139template<>
140const char*& EclKW_ref< const char* >::operator[]( size_t i ) = delete;
141
142template<>
143bool& EclKW_ref<bool>::operator[]( size_t i) = delete;
144
145template< typename T >
146class EclKW : public EclKW_ref< T > {
147 private:
148 using base = EclKW_ref< T >;
149
150 public:
151 using EclKW_ref< T >::EclKW_ref;
152
153 EclKW( const EclKW& ) = delete;
154 EclKW( EclKW&& rhs ) : base( rhs.m_kw ) {
155 rhs.m_kw = nullptr;
156 }
157
159 if( this->m_kw ) ecl_kw_free( this->m_kw );
160 }
161
162 EclKW( const std::string& kw, int size_ ) :
163 base( ecl_kw_alloc( kw.c_str(), size_, ecl_type_create_from_type(ecl_type< T >::type) ) )
164 {}
165
166 EclKW( const std::string& kw, const std::vector< T >& data ) :
167 EclKW( kw, data.size() )
168 {
169 ecl_kw_set_memcpy_data( this->m_kw, data.data() );
170 }
171
172 template< typename U >
173 EclKW( const std::string& kw, const std::vector< U >& data ) :
174 EclKW( kw, data.size() )
175 {
176 T* target = static_cast< T* >( ecl_kw_get_ptr( this->m_kw ) );
177
178 for( size_t i = 0; i < data.size(); ++i )
179 target[ i ] = T( data[ i ] );
180 }
181
182
183 std::vector<T> data() const {
184 const T* ptr = static_cast<T*>(ecl_kw_get_ptr(this->m_kw));
185 std::vector<T> vector;
186 vector.assign(ptr, ptr + this->size());
187 return vector;
188 }
189
190 static EclKW load( FortIO& fortio ) {
191 ecl_kw_type* c_ptr = ecl_kw_fread_alloc( fortio.get() );
192
193 if( !c_ptr )
194 throw std::invalid_argument("fread kw failed - EOF?");
195
196 return EclKW( c_ptr );
197 }
198
199};
200
201
202template<> inline
204 const std::vector< const char* >& data ) :
205 EclKW( kw, data.size() )
206{
207 auto* ptr = this->get();
208 for( size_t i = 0; i < data.size(); ++i ) {
209 if (strlen(data[i]) > 8)
210 throw std::range_error("Strings must be maximum 8 characters long");
211 ecl_kw_iset_string8( ptr, i, data[ i ] );
212 }
213}
214
215template<> inline
217 const std::vector< std::string >& data ) :
218 EclKW( kw, data.size() )
219{
220 auto* ptr = this->get();
221 for( size_t i = 0; i < data.size(); ++i ) {
222 if (data[i].size() > 8)
223 throw std::range_error("Strings must be maximum 8 characters long");
224 ecl_kw_iset_string8( ptr, i, data[ i ].c_str() );
225 }
226}
227
228
229template<>
230template<> inline
232 const std::vector< const char* >& data ) :
233 EclKW( kw, data.size() )
234{
235 auto* ptr = this->get();
236 for( size_t i = 0; i < data.size(); ++i) {
237 if (strlen(data[i]) > 8)
238 throw std::range_error("Strings must be maximum 8 characters long");
239 ecl_kw_iset_string8( ptr, i, data[ i ]);
240 }
241}
242
243template<> inline
244EclKW<bool>::EclKW( const std::string& kw, const std::vector< bool >& data ) :
245 EclKW( kw, data.size() )
246{
247 for (size_t i = 0; i < data.size(); i++)
248 ecl_kw_iset_bool( this->m_kw, i, data[i]);
249}
250
251template<> inline
252std::vector<std::string> EclKW<std::string>::data() const
253{
254 std::vector<std::string> strings;
255 auto* ptr = this->get();
256 for( size_t i = 0; i < this->size(); ++i ) {
258 s8.erase(s8.find_last_not_of(' ')+1);
259 strings.push_back( s8 );
260 }
261 return strings;
262}
263
264/*
265 Will write an ecl_kw instance to the open Fortio file.
266*/
267template<typename T>
268void write_kw(FortIO& fortio, const std::string& kw, const std::vector<T>& data) {
269 EclKW<T> ecl_kw(kw, data);
270 ecl_kw_fwrite(ecl_kw.get(), fortio.get());
271}
272
273/*
274 Will write an empty ecl_kw instance of type 'MESS' to the Fortio file.
275*/
276inline void write_mess(FortIO& fortio, const std::string& kw) {
277 ecl_kw_type * ecl_kw = ecl_kw_alloc(kw.c_str(), 0, ECL_MESS);
278 ecl_kw_fwrite(ecl_kw, fortio.get());
279}
280
281}
282
283#endif
const char *const string
Definition: cJSON.h:170
Definition: EclKW.hpp:68
const char * name() const
Definition: EclKW.hpp:77
ecl_kw_type * get() const
Definition: EclKW.hpp:102
const std::remove_pointer< T >::type * data() const
Definition: EclKW.hpp:97
T & operator[](size_t i)
Definition: EclKW.hpp:93
ecl_kw_type * m_kw
Definition: EclKW.hpp:111
T at(size_t i) const
Definition: EclKW.hpp:89
void fwrite(FortIO &fortio) const
Definition: EclKW.hpp:85
EclKW_ref(ecl_kw_type *kw)
Definition: EclKW.hpp:70
void resize(size_t new_size)
Definition: EclKW.hpp:106
EclKW_ref() noexcept=default
size_t size() const
Definition: EclKW.hpp:81
Definition: EclKW.hpp:146
~EclKW()
Definition: EclKW.hpp:158
std::vector< T > data() const
Definition: EclKW.hpp:183
static EclKW load(FortIO &fortio)
Definition: EclKW.hpp:190
EclKW(const std::string &kw, const std::vector< U > &data)
Definition: EclKW.hpp:173
EclKW(const std::string &kw, const std::vector< T > &data)
Definition: EclKW.hpp:166
EclKW(const EclKW &)=delete
EclKW(EclKW &&rhs)
Definition: EclKW.hpp:154
EclKW(const std::string &kw, int size_)
Definition: EclKW.hpp:162
Definition: FortIO.hpp:36
fortio_type * get() const
void ecl_kw_set_memcpy_data(ecl_kw_type *, const void *)
ecl_data_type ecl_kw_get_data_type(const ecl_kw_type *)
int ecl_kw_get_size(const ecl_kw_type *)
void ecl_kw_iset_string8(ecl_kw_type *ecl_kw, int index, const char *s8)
void ecl_kw_iset_bool(ecl_kw_type *ecl_kw, int i, bool bool_value)
ecl_kw_type * ecl_kw_fread_alloc(fortio_type *)
bool ecl_kw_fwrite(const ecl_kw_type *, fortio_type *)
void ecl_kw_free(ecl_kw_type *)
void * ecl_kw_iget_ptr(const ecl_kw_type *, int)
void ecl_kw_resize(ecl_kw_type *ecl_kw, int new_size)
void * ecl_kw_get_ptr(const ecl_kw_type *ecl_kw)
ecl_kw_type * ecl_kw_alloc(const char *header, int size, ecl_data_type)
struct ecl_kw_struct ecl_kw_type
Definition: ecl_kw.hpp:39
const char * ecl_kw_iget_char_ptr(const ecl_kw_type *ecl_kw, int i)
const char * ecl_kw_get_header(const ecl_kw_type *ecl_kw)
bool ecl_kw_iget_bool(const ecl_kw_type *ecl_kw, int i)
ecl_type_enum ecl_type_get_type(const ecl_data_type)
#define ECL_MESS
Definition: ecl_type.hpp:96
ecl_type_enum
Definition: ecl_type.hpp:44
@ ECL_FLOAT_TYPE
Definition: ecl_type.hpp:46
@ ECL_INT_TYPE
Definition: ecl_type.hpp:48
@ ECL_CHAR_TYPE
Definition: ecl_type.hpp:45
@ ECL_BOOL_TYPE
Definition: ecl_type.hpp:49
@ ECL_DOUBLE_TYPE
Definition: ecl_type.hpp:47
ecl_data_type ecl_type_create_from_type(const ecl_type_enum)
char bool
Definition: msvc_stdbool.h:17
Definition: EclFilename.hpp:25
void write_kw(FortIO &fortio, const std::string &kw, const std::vector< T > &data)
Definition: EclKW.hpp:268
void write_mess(FortIO &fortio, const std::string &kw)
Definition: EclKW.hpp:276
function get(const std::string &func, double alpha, double beta)
static std::string data()
Definition: exprtk.hpp:40022
Definition: EclKW.hpp:35