From 5424ddaf86fe3d935b7a0da326c024a4ba484c5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Wed, 27 Jun 2012 10:44:51 +0200 Subject: [PATCH 1/5] Fix inverted logic. Symbol NDEBUG is *defined* in release mode. --- opm/core/grid/cpgpreprocess/preprocess.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opm/core/grid/cpgpreprocess/preprocess.c b/opm/core/grid/cpgpreprocess/preprocess.c index bcd39c15..fe2b4a86 100644 --- a/opm/core/grid/cpgpreprocess/preprocess.c +++ b/opm/core/grid/cpgpreprocess/preprocess.c @@ -627,7 +627,7 @@ ind2sub(const size_t nx, { assert (c < (nx * ny * nz)); -#if !defined(NDEBUG) +#if defined(NDEBUG) (void) nz; #endif From 11d90ddeabf3926cf503baa78d095972f80f6f06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Wed, 27 Jun 2012 16:25:46 +0200 Subject: [PATCH 2/5] Add AC macro to determine how to link Boost.Test Details: Test suites based on Boost.Test must know how to include the library support code into the executables. If the Boost.Test library is dynamically linked, then test suites must define the pre-processor symbol "BOOST_TEST_DYN_LINK". Otherwise, this symbol must *not* be defined. Resolution: Introduce a new Autoconf macro, OPM_DYNLINK_BOOST_TEST, that defines a secondary symbol--HAVE_DYNAMIC_BOOST_TEST--if the local computer system uses dynamic linking. Test suites (e.g., tests/param_test.cpp) may then inspect this symbol to determine whether or not to #define BOOST_TEST_DYN_LINK. Call the macro from "configure.ac". Suggested by: Joakim Hove --- configure.ac | 2 + m4/opm_dynlink_boost_test.m4 | 80 ++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 m4/opm_dynlink_boost_test.m4 diff --git a/configure.ac b/configure.ac index 7f82ebcc..ef5fc0d8 100644 --- a/configure.ac +++ b/configure.ac @@ -44,6 +44,8 @@ AX_BOOST_UNIT_TEST_FRAMEWORK AX_DUNE_ISTL OPM_AGMG +OPM_DYNLINK_BOOST_TEST + # Checks for header files. AC_CHECK_HEADERS([float.h limits.h stddef.h stdlib.h string.h]) diff --git a/m4/opm_dynlink_boost_test.m4 b/m4/opm_dynlink_boost_test.m4 new file mode 100644 index 00000000..89c82908 --- /dev/null +++ b/m4/opm_dynlink_boost_test.m4 @@ -0,0 +1,80 @@ +# _OPM_DYNLINK_BOOST_TEST_SRC(Symbol) +# Generate source text for use in AC_LINK_IFELSE when determining +# how to link the Boost.Test library. +# +# Note: +# We use AC_LANG_SOURCE rather than AC_LANG_PROGRAM to avoid +# multiple definitions of "main()" (defined by both the UTF +# *and* the AC_LANG_PROGRAM macro). +AC_DEFUN([_OPM_DYNLINK_BOOST_TEST_SRC], +[AC_LANG_SOURCE( +[[$1 +#define BOOST_TEST_MODULE OPM_DYNLINK_TEST +#include + +int f(int x) { return 2 * x; } + +BOOST_AUTO_TEST_CASE(DynlinkConfigureTest) { + BOOST_CHECK_MESSAGE(f(2) == 4, + "Apparently, multiplication doesn't " + "work: f(2) = " << f(2)); +} +]]dnl +)[]dnl +]) + +dnl ------------------------------------------------------------------- + +# OPM_DYNLINK_BOOST_TEST +# Determine how to link (or compile+link) tests based on the UTF. +# +# If the system uses dynamic linking, then all tests need to +# +# #define BOOST_TEST_DYN_LINK +# +# Otherwise, this symbol must *not* be #define'd. +# +# Macro defines the symbol HAVE_DYNAMIC_BOOST_TEST (to 1) if the +# system uses dynamic linking of Boost.Test . +AC_DEFUN([OPM_DYNLINK_BOOST_TEST], +[ +AC_REQUIRE([AX_BOOST_BASE]) +AC_REQUIRE([AX_BOOST_UNIT_TEST_FRAMEWORK]) + +_opm_LIBS_SAVE="$LIBS" +_opm_CPPFLAGS_SAVE="$CPPFLAGS" + +LIBS="${BOOST_LDFLAGS} ${BOOST_UNIT_TEST_FRAMEWORK_LIB} ${LIBS}" +CPPFLAGS="${BOOST_CPPFLAGS} ${CPPFLAGS}" + +AC_LANG_PUSH([C++]) + +AC_CACHE_CHECK([if the Boost.Test library can be linked statically],dnl +[opm_cv_boost_link_static],dnl +[AC_LINK_IFELSE([_OPM_DYNLINK_BOOST_TEST_SRC([])], + [opm_cv_boost_link_static=yes],dnl + [opm_cv_boost_link_static=no])[]dnl +])[]dnl + +AC_CACHE_CHECK([if the Boost.Test library can be linked dynamically],dnl +[opm_cv_boost_link_dynamic],dnl +[AC_LINK_IFELSE([_OPM_DYNLINK_BOOST_TEST_SRC(dnl +[#define BOOST_TEST_DYN_LINK])], + [opm_cv_boost_link_dynamic=yes],dnl + [opm_cv_boost_link_dynamic=no])[]dnl +])[]dnl + +AC_LANG_POP([C++]) + +LIBS="$_opm_LIBS_SAVE" +CPPFLAGS="$_opm_CPPFLAGS_SAVE" + +AS_IF([test x"$opm_cv_boost_link_static" = x"yes" -o \ + x"$opm_cv_boost_link_dynamic" = x"yes"], +[AS_IF([test x"$opm_cv_boost_link_dynamic" = x"yes"], + [AC_DEFINE([HAVE_DYNAMIC_BOOST_TEST], [1], + [Define to `1' if Boost.Test should use BOOST_TEST_DYN_LINK])] + [:])[]dnl +],dnl +[AC_MSG_NOTICE([Boost.Test is not supported on this system])]) +])[]dnl From be1ca06fa3779f3466c4887b01ff9b82e20439c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Wed, 27 Jun 2012 16:51:37 +0200 Subject: [PATCH 3/5] Use dynamic Boost.Test mode only if supported Use result of OPM_DYNLINK_BOOST_TEST to determine whether or not to #define the Boost symbol BOOST_TEST_DYN_LINK . While here, replace an unprintable character with the proper UTF-8 encoding in a comment. --- tests/param_test.cpp | 6 +++++- tests/sparsetable_test.cpp | 6 +++++- tests/sparsevector_test.cpp | 5 ++++- tests/test_column_extract.cpp | 4 +++- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/tests/param_test.cpp b/tests/param_test.cpp index b5cbe8ba..afb0cc51 100644 --- a/tests/param_test.cpp +++ b/tests/param_test.cpp @@ -5,7 +5,7 @@ // Created: Sun Dec 13 20:08:36 2009 // // Author(s): Atgeirr F Rasmussen -// Bård Skaflestad +// BÃ¥rd Skaflestad // // $Date$ // @@ -34,7 +34,11 @@ */ +#include + +#if HAVE_DYNAMIC_BOOST_TEST #define BOOST_TEST_DYN_LINK +#endif #define NVERBOSE // to suppress our messages when throwing #define BOOST_TEST_MODULE ParameterTest diff --git a/tests/sparsetable_test.cpp b/tests/sparsetable_test.cpp index a5016adc..6d88e783 100644 --- a/tests/sparsetable_test.cpp +++ b/tests/sparsetable_test.cpp @@ -5,7 +5,7 @@ // Created: Thu May 28 10:01:46 2009 // // Author(s): Atgeirr F Rasmussen -// Bård Skaflestad +// BÃ¥rd Skaflestad // // $Date$ // @@ -33,7 +33,11 @@ along with OpenRS. If not, see . */ +#include + +#if HAVE_DYNAMIC_BOOST_TEST #define BOOST_TEST_DYN_LINK +#endif #define NVERBOSE // to suppress our messages when throwing #define BOOST_TEST_MODULE SparseTableTest diff --git a/tests/sparsevector_test.cpp b/tests/sparsevector_test.cpp index fa044fb5..a6f89be0 100644 --- a/tests/sparsevector_test.cpp +++ b/tests/sparsevector_test.cpp @@ -5,7 +5,7 @@ // Created: Mon Jun 29 21:00:53 2009 // // Author(s): Atgeirr F Rasmussen -// Bård Skaflestad +// BÃ¥rd Skaflestad // // $Date$ // @@ -33,8 +33,11 @@ along with OpenRS. If not, see . */ +#include +#if HAVE_DYNAMIC_BOOST_TEST #define BOOST_TEST_DYN_LINK +#endif #define NVERBOSE // to suppress our messages when throwing #define BOOST_TEST_MODULE SparseVectorTest diff --git a/tests/test_column_extract.cpp b/tests/test_column_extract.cpp index 46b1d538..9092b540 100644 --- a/tests/test_column_extract.cpp +++ b/tests/test_column_extract.cpp @@ -1,7 +1,9 @@ +#include - +#if HAVE_DYNAMIC_BOOST_TEST #define BOOST_TEST_DYN_LINK +#endif #define NVERBOSE // to suppress our messages when throwing #define BOOST_TEST_MODULE ColumnExtractTest From 93c813bf00c3006299224bd3d1403a35913513ce Mon Sep 17 00:00:00 2001 From: Joakim Hove Date: Thu, 28 Jun 2012 13:05:33 +0200 Subject: [PATCH 4/5] Added DataMap.hpp --- opm/core/utility/DataMap.hpp | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 opm/core/utility/DataMap.hpp diff --git a/opm/core/utility/DataMap.hpp b/opm/core/utility/DataMap.hpp new file mode 100644 index 00000000..833f7bcc --- /dev/null +++ b/opm/core/utility/DataMap.hpp @@ -0,0 +1,32 @@ +/* + Copyright 2012 SINTEF ICT, Applied Mathematics. + + 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 OPM_DATAMAP_HEADER_INCLUDED +#define OPM_DATAMAP_HEADER_INCLUDED + +#include +#include + +namespace Opm +{ + /// Intended to map strings (giving the output field names) to data. + typedef std::map*> DataMap; +} + +#endif From 01f43b18d70357db637c1d9aa833e7055c153539 Mon Sep 17 00:00:00 2001 From: Joakim Hove Date: Thu, 28 Jun 2012 13:20:18 +0200 Subject: [PATCH 5/5] Using Datamapper.h in writeVtkData --- opm/core/utility/writeVtkData.cpp | 501 +++++++++++++++--------------- opm/core/utility/writeVtkData.hpp | 14 +- 2 files changed, 257 insertions(+), 258 deletions(-) diff --git a/opm/core/utility/writeVtkData.cpp b/opm/core/utility/writeVtkData.cpp index 07e57172..3c70016e 100644 --- a/opm/core/utility/writeVtkData.cpp +++ b/opm/core/utility/writeVtkData.cpp @@ -18,6 +18,7 @@ */ #include +#include #include #include #include @@ -34,63 +35,63 @@ namespace Opm { void writeVtkData(const std::tr1::array& dims, - const std::tr1::array& cell_size, - const DataMap& data, - std::ostream& os) + const std::tr1::array& cell_size, + const DataMap& data, + std::ostream& os) { - // Dimension is hardcoded in the prototype and the next two lines, - // but the rest is flexible (allows dimension == 2 or 3). - int dimension = 3; - int num_cells = dims[0]*dims[1]*dims[2]; + // Dimension is hardcoded in the prototype and the next two lines, + // but the rest is flexible (allows dimension == 2 or 3). + int dimension = 3; + int num_cells = dims[0]*dims[1]*dims[2]; - ASSERT(dimension == 2 || dimension == 3); - ASSERT(num_cells == dims[0]*dims[1]* (dimension == 2 ? 1 : dims[2])); + ASSERT(dimension == 2 || dimension == 3); + ASSERT(num_cells == dims[0]*dims[1]* (dimension == 2 ? 1 : dims[2])); - os << "# vtk DataFile Version 2.0\n"; - os << "Structured Grid\n \n"; - os << "ASCII \n"; - os << "DATASET STRUCTURED_POINTS\n"; + os << "# vtk DataFile Version 2.0\n"; + os << "Structured Grid\n \n"; + os << "ASCII \n"; + os << "DATASET STRUCTURED_POINTS\n"; - os << "DIMENSIONS " - << dims[0] + 1 << " " - << dims[1] + 1 << " "; - if (dimension == 3) { - os << dims[2] + 1; - } else { - os << 1; - } - os << "\n"; - - os << "ORIGIN " << 0.0 << " " << 0.0 << " " << 0.0 << "\n"; + os << "DIMENSIONS " + << dims[0] + 1 << " " + << dims[1] + 1 << " "; + if (dimension == 3) { + os << dims[2] + 1; + } else { + os << 1; + } + os << "\n"; + + os << "ORIGIN " << 0.0 << " " << 0.0 << " " << 0.0 << "\n"; - os << "SPACING " << cell_size[0] << " " << cell_size[1]; - if (dimension == 3) { - os << " " << cell_size[2]; - } else { - os << " " << 0.0; - } - os << "\n"; + os << "SPACING " << cell_size[0] << " " << cell_size[1]; + if (dimension == 3) { + os << " " << cell_size[2]; + } else { + os << " " << 0.0; + } + os << "\n"; - os << "\nCELL_DATA " << num_cells << '\n'; - for (DataMap::const_iterator dit = data.begin(); dit != data.end(); ++dit) { - std::string name = dit->first; - os << "SCALARS " << name << " float" << '\n'; - os << "LOOKUP_TABLE " << name << "_table " << '\n'; - const std::vector& field = *(dit->second); - // We always print only the first data item for every - // cell, using 'stride'. - // This is a hack to get water saturation nicely. - // \TODO: Extend to properly printing vector data. - const int stride = field.size()/num_cells; - const int num_per_line = 5; - for (int c = 0; c < num_cells; ++c) { - os << field[stride*c] << ' '; - if (c % num_per_line == num_per_line - 1 - || c == num_cells - 1) { - os << '\n'; - } - } - } + os << "\nCELL_DATA " << num_cells << '\n'; + for (DataMap::const_iterator dit = data.begin(); dit != data.end(); ++dit) { + std::string name = dit->first; + os << "SCALARS " << name << " float" << '\n'; + os << "LOOKUP_TABLE " << name << "_table " << '\n'; + const std::vector& field = *(dit->second); + // We always print only the first data item for every + // cell, using 'stride'. + // This is a hack to get water saturation nicely. + // \TODO: Extend to properly printing vector data. + const int stride = field.size()/num_cells; + const int num_per_line = 5; + for (int c = 0; c < num_cells; ++c) { + os << field[stride*c] << ' '; + if (c % num_per_line == num_per_line - 1 + || c == num_cells - 1) { + os << '\n'; + } + } + } } typedef std::map PMap; @@ -98,219 +99,219 @@ namespace Opm struct Tag { - Tag(const std::string& tag, const PMap& props, std::ostream& os) - : name_(tag), os_(os) - { - indent(os); - os << "<" << tag; - for (PMap::const_iterator it = props.begin(); it != props.end(); ++it) { - os << " " << it->first << "=\"" << it->second << "\""; - } - os << ">\n"; - ++indent_; - } - Tag(const std::string& tag, std::ostream& os) - : name_(tag), os_(os) - { - indent(os); - os << "<" << tag << ">\n"; - ++indent_; - } - ~Tag() - { - --indent_; - indent(os_); - os_ << "\n"; - } - static void indent(std::ostream& os) - { - for (int i = 0; i < indent_; ++i) { - os << " "; - } - } + Tag(const std::string& tag, const PMap& props, std::ostream& os) + : name_(tag), os_(os) + { + indent(os); + os << "<" << tag; + for (PMap::const_iterator it = props.begin(); it != props.end(); ++it) { + os << " " << it->first << "=\"" << it->second << "\""; + } + os << ">\n"; + ++indent_; + } + Tag(const std::string& tag, std::ostream& os) + : name_(tag), os_(os) + { + indent(os); + os << "<" << tag << ">\n"; + ++indent_; + } + ~Tag() + { + --indent_; + indent(os_); + os_ << "\n"; + } + static void indent(std::ostream& os) + { + for (int i = 0; i < indent_; ++i) { + os << " "; + } + } private: - static int indent_; - std::string name_; - std::ostream& os_; + static int indent_; + std::string name_; + std::ostream& os_; }; int Tag::indent_ = 0; void writeVtkData(const UnstructuredGrid& grid, - const DataMap& data, - std::ostream& os) + const DataMap& data, + std::ostream& os) { - if (grid.dimensions != 3) { - THROW("Vtk output for 3d grids only"); - } - os.precision(12); - os << "\n"; - PMap pm; - pm["type"] = "UnstructuredGrid"; - Tag vtkfiletag("VTKFile", pm, os); - Tag ugtag("UnstructuredGrid", os); - int num_pts = grid.number_of_nodes; - int num_cells = grid.number_of_cells; - pm.clear(); - pm["NumberOfPoints"] = boost::lexical_cast(num_pts); - pm["NumberOfCells"] = boost::lexical_cast(num_cells); - Tag piecetag("Piece", pm, os); - { - Tag pointstag("Points", os); - pm.clear(); - pm["type"] = "Float64"; - pm["Name"] = "Coordinates"; - pm["NumberOfComponents"] = "3"; - pm["format"] = "ascii"; - Tag datag("DataArray", pm, os); - for (int i = 0; i < num_pts; ++i) { - Tag::indent(os); - os << grid.node_coordinates[3*i + 0] << ' ' - << grid.node_coordinates[3*i + 1] << ' ' - << grid.node_coordinates[3*i + 2] << '\n'; - } - } - { - Tag cellstag("Cells", os); - pm.clear(); - pm["type"] = "Int32"; - pm["NumberOfComponents"] = "1"; - pm["format"] = "ascii"; - std::vector cell_numpts; - cell_numpts.reserve(num_cells); - { - pm["Name"] = "connectivity"; - Tag t("DataArray", pm, os); - int hf = 0; - for (int c = 0; c < num_cells; ++c) { - std::set cell_pts; - for (; hf < grid.cell_facepos[c+1]; ++hf) { - int f = grid.cell_faces[hf]; - const int* fnbeg = grid.face_nodes + grid.face_nodepos[f]; - const int* fnend = grid.face_nodes + grid.face_nodepos[f+1]; - cell_pts.insert(fnbeg, fnend); - } - cell_numpts.push_back(cell_pts.size()); - Tag::indent(os); - std::copy(cell_pts.begin(), cell_pts.end(), - std::ostream_iterator(os, " ")); - os << '\n'; - } - } - { - pm["Name"] = "offsets"; - Tag t("DataArray", pm, os); - int offset = 0; - const int num_per_line = 10; - for (int c = 0; c < num_cells; ++c) { - if (c % num_per_line == 0) { - Tag::indent(os); - } - offset += cell_numpts[c]; - os << offset << ' '; - if (c % num_per_line == num_per_line - 1 - || c == num_cells - 1) { - os << '\n'; - } - } - } - std::vector cell_foffsets; - cell_foffsets.reserve(num_cells); - { - pm["Name"] = "faces"; - Tag t("DataArray", pm, os); - const int* fp = grid.cell_facepos; - int offset = 0; - for (int c = 0; c < num_cells; ++c) { - Tag::indent(os); - os << fp[c+1] - fp[c] << '\n'; - ++offset; - for (int hf = fp[c]; hf < fp[c+1]; ++hf) { - int f = grid.cell_faces[hf]; - const int* np = grid.face_nodepos; - int f_num_pts = np[f+1] - np[f]; - Tag::indent(os); - os << f_num_pts << ' '; - ++offset; - std::copy(grid.face_nodes + np[f], - grid.face_nodes + np[f+1], - std::ostream_iterator(os, " ")); - os << '\n'; - offset += f_num_pts; - } - cell_foffsets.push_back(offset); - } - } - { - pm["Name"] = "faceoffsets"; - Tag t("DataArray", pm, os); - const int num_per_line = 10; - for (int c = 0; c < num_cells; ++c) { - if (c % num_per_line == 0) { - Tag::indent(os); - } - os << cell_foffsets[c] << ' '; - if (c % num_per_line == num_per_line - 1 - || c == num_cells - 1) { - os << '\n'; - } - } - } - { - pm["type"] = "UInt8"; - pm["Name"] = "types"; - Tag t("DataArray", pm, os); - const int num_per_line = 10; - for (int c = 0; c < num_cells; ++c) { - if (c % num_per_line == 0) { - Tag::indent(os); - } - os << "42 "; - if (c % num_per_line == num_per_line - 1 - || c == num_cells - 1) { - os << '\n'; - } - } - } - } - { - pm.clear(); - if (data.find("saturation") != data.end()) { - pm["Scalars"] = "saturation"; - } else if (data.find("pressure") != data.end()) { - pm["Scalars"] = "pressure"; - } - Tag celldatatag("CellData", pm, os); - pm.clear(); - pm["NumberOfComponents"] = "1"; - pm["format"] = "ascii"; - pm["type"] = "Float64"; - for (DataMap::const_iterator dit = data.begin(); dit != data.end(); ++dit) { - pm["Name"] = dit->first; - const std::vector& field = *(dit->second); - const int num_comps = field.size()/grid.number_of_cells; - pm["NumberOfComponents"] = boost::lexical_cast(num_comps); - Tag ptag("DataArray", pm, os); - const int num_per_line = num_comps == 1 ? 5 : num_comps; - for (int item = 0; item < num_cells*num_comps; ++item) { - if (item % num_per_line == 0) { - Tag::indent(os); - } + if (grid.dimensions != 3) { + THROW("Vtk output for 3d grids only"); + } + os.precision(12); + os << "\n"; + PMap pm; + pm["type"] = "UnstructuredGrid"; + Tag vtkfiletag("VTKFile", pm, os); + Tag ugtag("UnstructuredGrid", os); + int num_pts = grid.number_of_nodes; + int num_cells = grid.number_of_cells; + pm.clear(); + pm["NumberOfPoints"] = boost::lexical_cast(num_pts); + pm["NumberOfCells"] = boost::lexical_cast(num_cells); + Tag piecetag("Piece", pm, os); + { + Tag pointstag("Points", os); + pm.clear(); + pm["type"] = "Float64"; + pm["Name"] = "Coordinates"; + pm["NumberOfComponents"] = "3"; + pm["format"] = "ascii"; + Tag datag("DataArray", pm, os); + for (int i = 0; i < num_pts; ++i) { + Tag::indent(os); + os << grid.node_coordinates[3*i + 0] << ' ' + << grid.node_coordinates[3*i + 1] << ' ' + << grid.node_coordinates[3*i + 2] << '\n'; + } + } + { + Tag cellstag("Cells", os); + pm.clear(); + pm["type"] = "Int32"; + pm["NumberOfComponents"] = "1"; + pm["format"] = "ascii"; + std::vector cell_numpts; + cell_numpts.reserve(num_cells); + { + pm["Name"] = "connectivity"; + Tag t("DataArray", pm, os); + int hf = 0; + for (int c = 0; c < num_cells; ++c) { + std::set cell_pts; + for (; hf < grid.cell_facepos[c+1]; ++hf) { + int f = grid.cell_faces[hf]; + const int* fnbeg = grid.face_nodes + grid.face_nodepos[f]; + const int* fnend = grid.face_nodes + grid.face_nodepos[f+1]; + cell_pts.insert(fnbeg, fnend); + } + cell_numpts.push_back(cell_pts.size()); + Tag::indent(os); + std::copy(cell_pts.begin(), cell_pts.end(), + std::ostream_iterator(os, " ")); + os << '\n'; + } + } + { + pm["Name"] = "offsets"; + Tag t("DataArray", pm, os); + int offset = 0; + const int num_per_line = 10; + for (int c = 0; c < num_cells; ++c) { + if (c % num_per_line == 0) { + Tag::indent(os); + } + offset += cell_numpts[c]; + os << offset << ' '; + if (c % num_per_line == num_per_line - 1 + || c == num_cells - 1) { + os << '\n'; + } + } + } + std::vector cell_foffsets; + cell_foffsets.reserve(num_cells); + { + pm["Name"] = "faces"; + Tag t("DataArray", pm, os); + const int* fp = grid.cell_facepos; + int offset = 0; + for (int c = 0; c < num_cells; ++c) { + Tag::indent(os); + os << fp[c+1] - fp[c] << '\n'; + ++offset; + for (int hf = fp[c]; hf < fp[c+1]; ++hf) { + int f = grid.cell_faces[hf]; + const int* np = grid.face_nodepos; + int f_num_pts = np[f+1] - np[f]; + Tag::indent(os); + os << f_num_pts << ' '; + ++offset; + std::copy(grid.face_nodes + np[f], + grid.face_nodes + np[f+1], + std::ostream_iterator(os, " ")); + os << '\n'; + offset += f_num_pts; + } + cell_foffsets.push_back(offset); + } + } + { + pm["Name"] = "faceoffsets"; + Tag t("DataArray", pm, os); + const int num_per_line = 10; + for (int c = 0; c < num_cells; ++c) { + if (c % num_per_line == 0) { + Tag::indent(os); + } + os << cell_foffsets[c] << ' '; + if (c % num_per_line == num_per_line - 1 + || c == num_cells - 1) { + os << '\n'; + } + } + } + { + pm["type"] = "UInt8"; + pm["Name"] = "types"; + Tag t("DataArray", pm, os); + const int num_per_line = 10; + for (int c = 0; c < num_cells; ++c) { + if (c % num_per_line == 0) { + Tag::indent(os); + } + os << "42 "; + if (c % num_per_line == num_per_line - 1 + || c == num_cells - 1) { + os << '\n'; + } + } + } + } + { + pm.clear(); + if (data.find("saturation") != data.end()) { + pm["Scalars"] = "saturation"; + } else if (data.find("pressure") != data.end()) { + pm["Scalars"] = "pressure"; + } + Tag celldatatag("CellData", pm, os); + pm.clear(); + pm["NumberOfComponents"] = "1"; + pm["format"] = "ascii"; + pm["type"] = "Float64"; + for (DataMap::const_iterator dit = data.begin(); dit != data.end(); ++dit) { + pm["Name"] = dit->first; + const std::vector& field = *(dit->second); + const int num_comps = field.size()/grid.number_of_cells; + pm["NumberOfComponents"] = boost::lexical_cast(num_comps); + Tag ptag("DataArray", pm, os); + const int num_per_line = num_comps == 1 ? 5 : num_comps; + for (int item = 0; item < num_cells*num_comps; ++item) { + if (item % num_per_line == 0) { + Tag::indent(os); + } double value = field[item]; if (std::fabs(value) < std::numeric_limits::min()) { // Avoiding denormal numbers to work around // bug in Paraview. value = 0.0; } - os << value << ' '; - if (item % num_per_line == num_per_line - 1 - || item == num_cells - 1) { - os << '\n'; - } - } - } - } + os << value << ' '; + if (item % num_per_line == num_per_line - 1 + || item == num_cells - 1) { + os << '\n'; + } + } + } + } } } // namespace Opm diff --git a/opm/core/utility/writeVtkData.hpp b/opm/core/utility/writeVtkData.hpp index 200b2b26..96cdfac2 100644 --- a/opm/core/utility/writeVtkData.hpp +++ b/opm/core/utility/writeVtkData.hpp @@ -26,25 +26,23 @@ #include #include #include +#include struct UnstructuredGrid; namespace Opm { - /// Intended to map strings (giving the output field names) to data. - typedef std::map*> DataMap; - /// Vtk output for cartesian grids. void writeVtkData(const std::tr1::array& dims, - const std::tr1::array& cell_size, - const DataMap& data, - std::ostream& os); + const std::tr1::array& cell_size, + const DataMap& data, + std::ostream& os); /// Vtk output for general grids. void writeVtkData(const UnstructuredGrid& grid, - const DataMap& data, - std::ostream& os); + const DataMap& data, + std::ostream& os); } // namespace Opm #endif // OPM_WRITEVTKDATA_HEADER_INCLUDED