opm-common
EclOutput.hpp
1 /*
2  Copyright 2019 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 it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  OPM is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with OPM. If not, see <http://www.gnu.org/licenses/>.
17  */
18 #ifndef OPM_IO_ECLOUTPUT_HPP
19 #define OPM_IO_ECLOUTPUT_HPP
20 
21 #include <opm/io/eclipse/EclIOdata.hpp>
22 #include <opm/io/eclipse/PaddedOutputString.hpp>
23 
24 #include <cstdint>
25 #include <fstream>
26 #include <ios>
27 #include <stdexcept>
28 #include <string>
29 #include <type_traits>
30 #include <vector>
31 
32 namespace Opm::EclIO::OutputStream {
33  class Restart;
34  class SummarySpecification;
35 } // namespace Opm::EclIO::OutputStream
36 
37 namespace Opm::EclIO {
38 
39 class EclOutput
40 {
41 public:
42  EclOutput(const std::string& filename,
43  const bool formatted,
44  const std::ios_base::openmode mode = std::ios::out);
45 
46  template<typename T>
47  void write(const std::string& name,
48  const std::vector<T>& data)
49  {
50  static_assert(std::is_same_v<T, int> ||
51  std::is_same_v<T, float> ||
52  std::is_same_v<T, double> ||
53  std::is_same_v<T, bool> ||
54  std::is_same_v<T, char>,
55  "EclOutput::write<T>: T must be int, float, double, bool, or char");
56 
57  eclArrType arrType = MESS;
58  int element_size = 4;
59 
60  if constexpr (std::is_same_v<T, int>) {
61  arrType = INTE;
62  }
63  else if constexpr (std::is_same_v<T, float>) {
64  arrType = REAL;
65  }
66  else if constexpr (std::is_same_v<T, double>) {
67  arrType = DOUB;
68  element_size = 8;
69  }
70  else if constexpr (std::is_same_v<T, bool>) {
71  arrType = LOGI;
72  }
73  else if constexpr (std::is_same_v<T, char>) {
74  if (!data.empty()) {
75  throw std::invalid_argument {
76  "EclOutput::write<char>: non-empty data is not supported; "
77  "use message() for MESS-type records"
78  };
79  }
80  }
81 
82  if (isFormatted) {
83  writeFormattedHeader(name, data.size(), arrType, element_size);
84  if (arrType != MESS) {
85  writeFormattedArray(data);
86  }
87  }
88  else {
89  writeBinaryHeader(name, data.size(), arrType, element_size);
90  if (arrType != MESS) {
91  writeBinaryArray(data);
92  }
93  }
94  }
95 
96  // when this function is used array type will be assumed C0NN (not CHAR).
97  // Also in cases where element size is 8 or less, element size will be 8.
98 
99  void write(const std::string& name, const std::vector<std::string>& data, int element_size);
100 
101  void message(const std::string& msg);
102  void flushStream();
103 
104  void set_ix() { ix_standard = true; }
105 
106  friend class OutputStream::Restart;
108 
109 private:
110  void writeStringVector(const std::string& name,
111  const std::vector<std::string>& strings,
112  const eclArrType charType,
113  const int charPerStr);
114 
115  void writeBinaryHeader(const std::string& arrName, std::int64_t size, eclArrType arrType, int element_size);
116 
117  template <typename T>
118  void writeBinaryArray(const std::vector<T>& data);
119 
120  void writeBinaryCharArray(const std::vector<std::string>& data, int element_size);
121  void writeBinaryCharArray(const std::vector<PaddedOutputString<8>>& data);
122 
123  void writeFormattedHeader(const std::string& arrName, int size, eclArrType arrType, int element_size);
124 
125  template <typename T>
126  void writeFormattedArray(const std::vector<T>& data);
127 
128  void writeFormattedCharArray(const std::vector<std::string>& data, int element_size);
129  void writeFormattedCharArray(const std::vector<PaddedOutputString<8>>& data);
130 
131  void writeArrayType(const eclArrType arrType);
132  std::string make_real_string_ecl(float value) const;
133  std::string make_real_string_ix(float value) const;
134  std::string make_doub_string_ecl(double value) const;
135  std::string make_doub_string_ix(double value) const;
136 
137  bool isFormatted, ix_standard;
138  std::ofstream ofileH;
139 };
140 
141 template<>
142 void EclOutput::write<std::string>(const std::string& name,
143  const std::vector<std::string>& data);
144 
145 template <>
146 void EclOutput::write<PaddedOutputString<8>>
147  (const std::string& name,
148  const std::vector<PaddedOutputString<8>>& data);
149 
150 } // namespace Opm::EclIO
151 
152 #endif // OPM_IO_ECLOUTPUT_HPP
Definition: OutputStream.hpp:379
File manager for restart output streams.
Definition: OutputStream.hpp:151
Definition: EclOutput.hpp:39
Definition: EclipseGrid.hpp:43
Definition: EclOutput.hpp:32
Null-terminated, left adjusted, space padded array of N characters.
Definition: PaddedOutputString.hpp:39