diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1490f2c2a..074f0d88e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -161,6 +161,7 @@ if(ENABLE_ECL_INPUT)
examples/test_util/EclFilesComparator.cpp
examples/test_util/EclIntegrationTest.cpp
examples/test_util/EclRegressionTest.cpp
+ examples/test_util/EclOutput.cpp
examples/test_util/EclUtil.cpp
examples/test_util/summaryComparator.cpp
examples/test_util/summaryIntegrationTest.cpp
diff --git a/examples/test_util/EclOutput.cpp b/examples/test_util/EclOutput.cpp
new file mode 100644
index 000000000..f56381823
--- /dev/null
+++ b/examples/test_util/EclOutput.cpp
@@ -0,0 +1,397 @@
+/*
+ Copyright 2019 Statoil ASA.
+
+ 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 .
+ */
+
+#include "EclOutput.hpp"
+#include "EclUtil.hpp"
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+EclOutput::EclOutput(const std::string& inputFile, bool formatted) :
+ isFormatted(formatted)
+{
+ ofileH.open(inputFile, isFormatted ? std::ios::out : std::ios::out | std::ios::binary);
+}
+
+
+template<>
+void EclOutput::write(const std::string& name,
+ const std::vector& data)
+{
+ if (isFormatted)
+ {
+ writeFormattedHeader(name, data.size(), EIOD::CHAR);
+ writeFormattedCharArray(data);
+ }
+ else
+ {
+ writeBinaryHeader(name, data.size(), EIOD::CHAR);
+ writeBinaryCharArray(data);
+ }
+}
+
+
+void EclOutput::writeBinaryHeader(const std::string&arrName, int size, EIOD::eclArrType arrType)
+{
+ std::string name = arrName + std::string(8 - arrName.size(),' ');
+
+ int flippedSize = EIOD::flipEndianInt(size);
+ int bhead = EIOD::flipEndianInt(16);
+
+ ofileH.write(reinterpret_cast(&bhead), sizeof(bhead));
+
+ ofileH.write(name.c_str(), 8);
+ ofileH.write(reinterpret_cast(&flippedSize), sizeof(flippedSize));
+
+ switch(arrType) {
+ case EIOD::INTE:
+ ofileH.write("INTE", 4);
+ break;
+ case EIOD::REAL:
+ ofileH.write("REAL", 4);
+ break;
+ case EIOD::DOUB:
+ ofileH.write("DOUB", 4);
+ break;
+ case EIOD::LOGI:
+ ofileH.write("LOGI", 4);
+ break;
+ case EIOD::CHAR:
+ ofileH.write("CHAR", 4);
+ break;
+ case EIOD::MESS:
+ ofileH.write("MESS", 4);
+ break;
+ }
+
+ ofileH.write(reinterpret_cast(&bhead), sizeof(bhead));
+}
+
+
+template
+void EclOutput::writeBinaryArray(const std::vector& data)
+{
+ int rest,num,rval;
+ int dhead;
+ float value_f;
+ double value_d;
+ int intVal;
+
+ int n = 0;
+ int size = data.size();
+
+ EIOD::eclArrType arrType = EIOD::MESS;
+
+ if (typeid(std::vector) == typeid(std::vector)) {
+ arrType = EIOD::INTE;
+ } else if (typeid(std::vector) == typeid(std::vector)) {
+ arrType = EIOD::REAL;
+ } else if (typeid(std::vector) == typeid(std::vector)) {
+ arrType = EIOD::DOUB;
+ } else if (typeid(std::vector) == typeid(std::vector)) {
+ arrType = EIOD::LOGI;
+ }
+
+ auto sizeData = block_size_data_binary(arrType);
+
+ int sizeOfElement = std::get<0>(sizeData);
+ int maxBlockSize = std::get<1>(sizeData);
+ int maxNumberOfElements = maxBlockSize / sizeOfElement;
+
+ if (!ofileH.is_open()) {
+ OPM_THROW(std::runtime_error, "fstream fileH not open for writing");
+ }
+
+ rest = size * sizeOfElement;
+ while (rest > 0) {
+ if (rest > maxBlockSize) {
+ rest -= maxBlockSize;
+ num = maxNumberOfElements;
+ } else {
+ num = rest / sizeOfElement;
+ rest = 0;
+ }
+
+ dhead = EIOD::flipEndianInt(num * sizeOfElement);
+
+ ofileH.write(reinterpret_cast(&dhead), sizeof(dhead));
+
+ for (int i = 0; i < num; i++) {
+ if (arrType == EIOD::INTE) {
+ rval = EIOD::flipEndianInt(data[n]);
+ ofileH.write(reinterpret_cast(&rval), sizeof(rval));
+ } else if (arrType == EIOD::REAL) {
+ value_f = EIOD::flipEndianFloat(data[n]);
+ ofileH.write(reinterpret_cast(&value_f), sizeof(value_f));
+ } else if (arrType == EIOD::DOUB) {
+ value_d = EIOD::flipEndianDouble(data[n]);
+ ofileH.write(reinterpret_cast(&value_d), sizeof(value_d));
+ } else if (arrType == EIOD::LOGI) {
+ intVal = data[n] ? EIOD::true_value : EIOD::false_value;
+ ofileH.write(reinterpret_cast(&intVal), sizeOfElement);
+ } else {
+ std::cout << "type not supported in write binaryarray" << std::endl;
+ exit(1);
+ }
+
+ n++;
+ }
+
+ ofileH.write(reinterpret_cast(&dhead), sizeof(dhead));
+ }
+}
+
+
+template void EclOutput::writeBinaryArray(const std::vector& data);
+template void EclOutput::writeBinaryArray(const std::vector& data);
+template void EclOutput::writeBinaryArray(const std::vector& data);
+template void EclOutput::writeBinaryArray(const std::vector& data);
+template void EclOutput::writeBinaryArray(const std::vector& data);
+
+
+void EclOutput::writeBinaryCharArray(const std::vector& data)
+{
+ int num,dhead;
+
+ int n = 0;
+ int size = data.size();
+
+ auto sizeData = EIOD::block_size_data_binary(EIOD::CHAR);
+
+ int sizeOfElement = std::get<0>(sizeData);
+ int maxBlockSize = std::get<1>(sizeData);
+ int maxNumberOfElements = maxBlockSize / sizeOfElement;
+
+ int rest = size * sizeOfElement;
+
+ if (!ofileH.is_open()) {
+ OPM_THROW(std::runtime_error,"fstream fileH not open for writing");
+ }
+
+ while (rest > 0) {
+ if (rest > maxBlockSize) {
+ rest -= maxBlockSize;
+ num = maxNumberOfElements;
+ } else {
+ num = rest / sizeOfElement;
+ rest = 0;
+ }
+
+ dhead = EIOD::flipEndianInt(num * sizeOfElement);
+
+ ofileH.write(reinterpret_cast(&dhead), sizeof(dhead));
+
+ for (int i = 0; i < num; i++) {
+ std::string tmpStr = data[n] + std::string(8 - data[n].size(),' ');
+ ofileH.write(tmpStr.c_str(), sizeOfElement);
+ n++;
+ }
+
+ ofileH.write(reinterpret_cast(&dhead), sizeof(dhead));
+ }
+}
+
+
+void EclOutput::writeFormattedHeader(const std::string& arrName, int size, EIOD::eclArrType arrType)
+{
+ std::string name = arrName + std::string(8 - arrName.size(),' ');
+
+ ofileH << " '" << name << "' " << std::setw(11) << size;
+
+ switch (arrType) {
+ case EIOD::INTE:
+ ofileH << " 'INTE'" << std::endl;
+ break;
+ case EIOD::REAL:
+ ofileH << " 'REAL'" << std::endl;
+ break;
+ case EIOD::DOUB:
+ ofileH << " 'DOUB'" << std::endl;
+ break;
+ case EIOD::LOGI:
+ ofileH << " 'LOGI'" << std::endl;
+ break;
+ case EIOD::CHAR:
+ ofileH << " 'CHAR'" << std::endl;
+ break;
+ case EIOD::MESS:
+ ofileH << " 'MESS'" << std::endl;
+ break;
+ }
+}
+
+
+std::string EclOutput::make_real_string(float value) const
+{
+ char buffer [15];
+ sprintf (buffer, "%10.7E", value);
+
+ if (value == 0.0) {
+ return "0.00000000E+00";
+ } else {
+ std::string tmpstr(buffer);
+
+ int exp = value < 0.0 ? std::stoi(tmpstr.substr(11, 3)) : std::stoi(tmpstr.substr(10, 3));
+
+ if (value < 0.0) {
+ tmpstr = "-0." + tmpstr.substr(1, 1) + tmpstr.substr(3, 7) + "E";
+ } else {
+ tmpstr = "0." + tmpstr.substr(0, 1) + tmpstr.substr(2, 7) +"E";
+ }
+
+ sprintf (buffer, "%+03i", exp+1);
+ tmpstr = tmpstr+buffer;
+
+ return tmpstr;
+ }
+}
+
+
+std::string EclOutput::make_doub_string(double value) const
+{
+ char buffer [20];
+ sprintf (buffer, "%19.13E", value);
+
+ if (value == 0.0) {
+ return "0.00000000000000D+00";
+ } else {
+ std::string tmpstr(buffer);
+
+ int exp = value < 0.0 ? std::stoi(tmpstr.substr(17, 4)) : std::stoi(tmpstr.substr(16, 4));
+
+ if (value < 0.0) {
+ if (abs(exp) < 100) {
+ tmpstr = "-0." + tmpstr.substr(1, 1) + tmpstr.substr(3, 13) + "D";
+ } else {
+ tmpstr = "-0." + tmpstr.substr(1, 1) + tmpstr.substr(3, 13);
+ }
+ } else {
+ if (abs(exp) < 100) {
+ tmpstr = "0." + tmpstr.substr(0, 1) + tmpstr.substr(2, 13) + "D";
+ } else {
+ tmpstr = "0." + tmpstr.substr(0, 1) + tmpstr.substr(2, 13);
+ }
+ }
+
+ sprintf (buffer, "%+03i", exp+1);
+ tmpstr = tmpstr + buffer;
+
+ return tmpstr;
+ }
+}
+
+
+template
+void EclOutput::writeFormattedArray(const std::vector& data)
+{
+ int size = data.size();
+ int n = 0;
+
+ EIOD::eclArrType arrType = EIOD::MESS;
+ if (typeid(T) == typeid(int)) {
+ arrType = EIOD::INTE;
+ } else if (typeid(T) == typeid(float)) {
+ arrType = EIOD::REAL;
+ } else if (typeid(T) == typeid(double)) {
+ arrType = EIOD::DOUB;
+ } else if (typeid(T) == typeid(bool)) {
+ arrType = EIOD::LOGI;
+ }
+
+ auto sizeData = EIOD::block_size_data_formatted(arrType);
+
+ int maxBlockSize = std::get<0>(sizeData);
+ int nColumns = std::get<1>(sizeData);
+ int columnWidth = std::get<2>(sizeData);
+
+ for (int i = 0; i < size; i++) {
+ n++;
+
+ switch (arrType) {
+ case EIOD::INTE:
+ ofileH << std::setw(columnWidth) << data[i];
+ break;
+ case EIOD::REAL:
+ ofileH << std::setw(columnWidth) << make_real_string(data[i]);
+ break;
+ case EIOD::DOUB:
+ ofileH << std::setw(columnWidth) << make_doub_string(data[i]);
+ break;
+ case EIOD::LOGI:
+ if (data[i]) {
+ ofileH << " T";
+ } else {
+ ofileH << " F";
+ }
+ break;
+ default:
+ break;
+ }
+
+ if ((n % nColumns) == 0 || (n % maxBlockSize) == 0) {
+ ofileH << std::endl;
+ }
+
+ if ((n % maxBlockSize) == 0) {
+ n=0;
+ }
+ }
+
+ if ((n % nColumns) != 0 && (n % maxBlockSize) != 0) {
+ ofileH << std::endl;
+ }
+}
+
+
+template void EclOutput::writeFormattedArray(const std::vector& data);
+template void EclOutput::writeFormattedArray(const std::vector& data);
+template void EclOutput::writeFormattedArray(const std::vector& data);
+template void EclOutput::writeFormattedArray(const std::vector& data);
+template void EclOutput::writeFormattedArray(const std::vector& data);
+
+
+void EclOutput::writeFormattedCharArray(const std::vector& data)
+{
+ auto sizeData = EIOD::block_size_data_formatted(EIOD::CHAR);
+
+ int nColumns = std::get<1>(sizeData);
+
+ int size = data.size();
+
+ for (int i = 0; i < size; i++) {
+ std::string str1(8,' ');
+ str1 = data[i] + std::string(8 - data[i].size(),' ');
+
+ ofileH << " '" << str1 << "'";
+
+ if ((i+1) % nColumns == 0) {
+ ofileH << std::endl;
+ }
+ }
+
+ if ((size % nColumns) != 0) {
+ ofileH << std::endl;
+ }
+}
diff --git a/examples/test_util/EclOutput.hpp b/examples/test_util/EclOutput.hpp
new file mode 100644
index 000000000..1d1825eb2
--- /dev/null
+++ b/examples/test_util/EclOutput.hpp
@@ -0,0 +1,94 @@
+/*
+ Copyright 2019 Statoil ASA.
+
+ 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 ECL_OUTPUT_HPP
+#define ECL_OUTPUT_HPP
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+namespace EIOD = Opm::ecl;
+
+
+class EclOutput
+{
+public:
+ EclOutput(const std::string& inputFile, bool formatted);
+
+ template
+ void write(const std::string& name,
+ const std::vector& data)
+ {
+ EIOD::eclArrType arrType = EIOD::MESS;
+ if (typeid(T) == typeid(int))
+ arrType = EIOD::INTE;
+ else if (typeid(T) == typeid(float))
+ arrType = EIOD::REAL;
+ else if (typeid(T) == typeid(double))
+ arrType = EIOD::DOUB;
+ else if (typeid(T) == typeid(bool))
+ arrType = EIOD::LOGI;
+ else if (typeid(T) == typeid(char))
+ arrType = EIOD::MESS;
+
+ if (isFormatted)
+ {
+ writeFormattedHeader(name, data.size(), arrType);
+ if (arrType != EIOD::MESS)
+ writeFormattedArray(data);
+ }
+ else
+ {
+ writeBinaryHeader(name, data.size(), arrType);
+ if (arrType != EIOD::MESS)
+ writeBinaryArray(data);
+ }
+ }
+
+private:
+ void writeBinaryHeader(const std::string& arrName, int size, EIOD::eclArrType arrType);
+
+ template
+ void writeBinaryArray(const std::vector& data);
+
+ void writeBinaryCharArray(const std::vector& data);
+
+ void writeFormattedHeader(const std::string& arrName, int size, EIOD::eclArrType arrType);
+
+ template
+ void writeFormattedArray(const std::vector& data);
+
+ void writeFormattedCharArray(const std::vector& data);
+
+ std::string make_real_string(float value) const;
+ std::string make_doub_string(double value) const;
+
+ std::ofstream ofileH;
+ bool isFormatted;
+};
+
+
+template<>
+void EclOutput::write(const std::string& name,
+ const std::vector& data);
+
+#endif