From 3e789272fdf75a4a5992b9b5480161437d324db1 Mon Sep 17 00:00:00 2001 From: Joakim Hove Date: Wed, 27 Jun 2012 08:06:22 +0200 Subject: [PATCH 01/38] Added configure.ac + Makefile.am support for including ert --- Makefile.am | 493 ++++++++++++++++++++++--------------------- configure.ac | 53 +++++ examples/Makefile.am | 29 +-- tests/Makefile.am | 45 ++-- tests/test_ert.cpp | 261 +++++++++++++++++++++++ 5 files changed, 609 insertions(+), 272 deletions(-) create mode 100644 tests/test_ert.cpp diff --git a/Makefile.am b/Makefile.am index feeb53c1..583e67ff 100644 --- a/Makefile.am +++ b/Makefile.am @@ -11,283 +11,294 @@ lib_LTLIBRARIES = libopmcore.la # ---------------------------------------------------------------------- # Build-time flags needed to build libopmcore.la -AM_CPPFLAGS = \ -$(BOOST_CPPFLAGS) +#----------------------------------------------------------------- +# ERT related settings +#if HAVE_ERT +ERT_LIB_PATH = $(ERT_ROOT)/lib +ERT_LIBS = -leclxx -lecl -lgeometry -lutil -lpthread -lz -lgomp +ERT_LDFLAGS = -L$(ERT_LIB_PATH) $(ERT_LIBS) +ERT_INCLUDE_PATH = $(ERT_ROOT)/include +ERT_CPPFLAGS = -I$(ERT_INCLUDE_PATH) +#endif + +AM_CPPFLAGS = \ +$(BOOST_CPPFLAGS) \ +-I$(ERT_INCLUDE_PATH) # ---------------------------------------------------------------------- # Link-time flags needed both to successfully link the library and to # (transitively) convey inter-library dependency information. -libopmcore_la_LDFLAGS = \ -$(BOOST_LDFLAGS) \ -$(BOOST_FILESYSTEM_LIB) \ -$(BOOST_SYSTEM_LIB) \ -$(BOOST_DATE_TIME_LIB) \ -$(BOOST_UNIT_TEST_FRAMEWORK_LIB) \ -$(LAPACK_LIBS) $(BLAS_LIBS) $(LIBS) $(FLIBS) +libopmcore_la_LDFLAGS = \ +$(BOOST_LDFLAGS) \ +$(BOOST_FILESYSTEM_LIB) \ +$(BOOST_SYSTEM_LIB) \ +$(BOOST_DATE_TIME_LIB) \ +$(BOOST_UNIT_TEST_FRAMEWORK_LIB) \ +$(ERT_LDFLAGS) $(LAPACK_LIBS) $(BLAS_LIBS) $(LIBS) $(FLIBS) # ---------------------------------------------------------------------- # Library constituents. SOURCES followed by HEADERS. # # Please try to keep the list sorted. -libopmcore_la_SOURCES = \ -opm/core/GridManager.cpp \ -opm/core/eclipse/EclipseGridInspector.cpp \ -opm/core/eclipse/EclipseGridParser.cpp \ -opm/core/fluid/BlackoilPropertiesBasic.cpp \ -opm/core/fluid/BlackoilPropertiesFromDeck.cpp \ -opm/core/fluid/IncompPropertiesBasic.cpp \ -opm/core/fluid/IncompPropertiesFromDeck.cpp \ -opm/core/fluid/PvtPropertiesBasic.cpp \ -opm/core/fluid/PvtPropertiesIncompFromDeck.cpp \ -opm/core/fluid/RockBasic.cpp \ -opm/core/fluid/RockCompressibility.cpp \ -opm/core/fluid/RockFromDeck.cpp \ -opm/core/fluid/SaturationPropsBasic.cpp \ -opm/core/fluid/SaturationPropsFromDeck.cpp \ -opm/core/fluid/blackoil/BlackoilPvtProperties.cpp \ -opm/core/fluid/blackoil/SinglePvtDead.cpp \ -opm/core/fluid/blackoil/SinglePvtInterface.cpp \ -opm/core/fluid/blackoil/SinglePvtLiveGas.cpp \ -opm/core/fluid/blackoil/SinglePvtLiveOil.cpp \ -opm/core/grid.c \ -opm/core/grid/cart_grid.c \ -opm/core/grid/cornerpoint_grid.c \ -opm/core/grid/cpgpreprocess/facetopology.c \ -opm/core/grid/cpgpreprocess/geometry.c \ -opm/core/grid/cpgpreprocess/preprocess.c \ -opm/core/grid/cpgpreprocess/readvector.cpp \ -opm/core/grid/cpgpreprocess/sparsetable.c \ -opm/core/grid/cpgpreprocess/uniquepoints.c \ -opm/core/linalg/LinearSolverFactory.cpp \ -opm/core/linalg/LinearSolverInterface.cpp \ -opm/core/linalg/sparse_sys.c \ -opm/core/newwells.c \ -opm/core/pressure/CompressibleTpfa.cpp \ -opm/core/pressure/FlowBCManager.cpp \ -opm/core/pressure/IncompTpfa.cpp \ -opm/core/pressure/cfsh.c \ -opm/core/pressure/flow_bc.c \ -opm/core/pressure/fsh.c \ -opm/core/pressure/fsh_common_impl.c \ -opm/core/pressure/ifsh.c \ -opm/core/pressure/mimetic/hybsys.c \ -opm/core/pressure/mimetic/hybsys_global.c \ -opm/core/pressure/mimetic/mimetic.c \ -opm/core/pressure/msmfem/coarse_conn.c \ -opm/core/pressure/msmfem/coarse_sys.c \ -opm/core/pressure/msmfem/dfs.c \ -opm/core/pressure/msmfem/hash_set.c \ -opm/core/pressure/msmfem/ifsh_ms.c \ -opm/core/pressure/msmfem/partition.c \ -opm/core/pressure/tpfa/cfs_tpfa.c \ -opm/core/pressure/tpfa/cfs_tpfa_residual.c \ -opm/core/pressure/tpfa/compr_bc.c \ -opm/core/pressure/tpfa/compr_quant.c \ -opm/core/pressure/tpfa/compr_quant_general.c \ -opm/core/pressure/tpfa/compr_source.c \ -opm/core/pressure/tpfa/ifs_tpfa.c \ -opm/core/pressure/tpfa/trans_tpfa.c \ -opm/core/pressure/well.c \ -opm/core/simulator/SimulatorReport.cpp \ -opm/core/simulator/SimulatorTimer.cpp \ -opm/core/simulator/SimulatorTwophase.cpp \ -opm/core/transport/reorder/TransportModelCompressibleTwophase.cpp \ -opm/core/transport/reorder/TransportModelInterface.cpp \ -opm/core/transport/reorder/TransportModelTwophase.cpp \ -opm/core/transport/reorder/nlsolvers.c \ -opm/core/transport/reorder/reordersequence.cpp \ -opm/core/transport/reorder/tarjan.c \ -opm/core/transport/spu_explicit.c \ -opm/core/transport/spu_implicit.c \ -opm/core/transport/transport_source.c \ -opm/core/utility/MonotCubicInterpolator.cpp \ -opm/core/utility/StopWatch.cpp \ -opm/core/utility/miscUtilities.cpp \ -opm/core/utility/miscUtilitiesBlackoil.cpp \ -opm/core/utility/parameters/Parameter.cpp \ -opm/core/utility/parameters/ParameterGroup.cpp \ -opm/core/utility/parameters/ParameterTools.cpp \ -opm/core/utility/parameters/ParameterXML.cpp \ -opm/core/utility/parameters/tinyxml/tinystr.cpp \ -opm/core/utility/parameters/tinyxml/tinyxml.cpp \ -opm/core/utility/parameters/tinyxml/tinyxmlerror.cpp \ -opm/core/utility/parameters/tinyxml/tinyxmlparser.cpp \ -opm/core/utility/writeVtkData.cpp \ -opm/core/vag_format/vag.cpp \ -opm/core/wells/InjectionSpecification.cpp \ -opm/core/wells/ProductionSpecification.cpp \ -opm/core/wells/WellCollection.cpp \ -opm/core/wells/WellsGroup.cpp \ +libopmcore_la_SOURCES = \ +opm/core/GridManager.cpp \ +opm/core/eclipse/EclipseGridInspector.cpp \ +opm/core/eclipse/EclipseGridParser.cpp \ +opm/core/fluid/BlackoilPropertiesBasic.cpp \ +opm/core/fluid/BlackoilPropertiesFromDeck.cpp \ +opm/core/fluid/IncompPropertiesBasic.cpp \ +opm/core/fluid/IncompPropertiesFromDeck.cpp \ +opm/core/fluid/PvtPropertiesBasic.cpp \ +opm/core/fluid/PvtPropertiesIncompFromDeck.cpp \ +opm/core/fluid/RockBasic.cpp \ +opm/core/fluid/RockCompressibility.cpp \ +opm/core/fluid/RockFromDeck.cpp \ +opm/core/fluid/SaturationPropsBasic.cpp \ +opm/core/fluid/SaturationPropsFromDeck.cpp \ +opm/core/fluid/blackoil/BlackoilPvtProperties.cpp \ +opm/core/fluid/blackoil/SinglePvtDead.cpp \ +opm/core/fluid/blackoil/SinglePvtInterface.cpp \ +opm/core/fluid/blackoil/SinglePvtLiveGas.cpp \ +opm/core/fluid/blackoil/SinglePvtLiveOil.cpp \ +opm/core/grid.c \ +opm/core/grid/cart_grid.c \ +opm/core/grid/cornerpoint_grid.c \ +opm/core/grid/cpgpreprocess/facetopology.c \ +opm/core/grid/cpgpreprocess/geometry.c \ +opm/core/grid/cpgpreprocess/preprocess.c \ +opm/core/grid/cpgpreprocess/readvector.cpp \ +opm/core/grid/cpgpreprocess/sparsetable.c \ +opm/core/grid/cpgpreprocess/uniquepoints.c \ +opm/core/linalg/LinearSolverFactory.cpp \ +opm/core/linalg/LinearSolverInterface.cpp \ +opm/core/linalg/sparse_sys.c \ +opm/core/newwells.c \ +opm/core/pressure/CompressibleTpfa.cpp \ +opm/core/pressure/FlowBCManager.cpp \ +opm/core/pressure/IncompTpfa.cpp \ +opm/core/pressure/cfsh.c \ +opm/core/pressure/flow_bc.c \ +opm/core/pressure/fsh.c \ +opm/core/pressure/fsh_common_impl.c \ +opm/core/pressure/ifsh.c \ +opm/core/pressure/mimetic/hybsys.c \ +opm/core/pressure/mimetic/hybsys_global.c \ +opm/core/pressure/mimetic/mimetic.c \ +opm/core/pressure/msmfem/coarse_conn.c \ +opm/core/pressure/msmfem/coarse_sys.c \ +opm/core/pressure/msmfem/dfs.c \ +opm/core/pressure/msmfem/hash_set.c \ +opm/core/pressure/msmfem/ifsh_ms.c \ +opm/core/pressure/msmfem/partition.c \ +opm/core/pressure/tpfa/cfs_tpfa.c \ +opm/core/pressure/tpfa/cfs_tpfa_residual.c \ +opm/core/pressure/tpfa/compr_bc.c \ +opm/core/pressure/tpfa/compr_quant.c \ +opm/core/pressure/tpfa/compr_quant_general.c \ +opm/core/pressure/tpfa/compr_source.c \ +opm/core/pressure/tpfa/ifs_tpfa.c \ +opm/core/pressure/tpfa/trans_tpfa.c \ +opm/core/pressure/well.c \ +opm/core/simulator/SimulatorReport.cpp \ +opm/core/simulator/SimulatorTimer.cpp \ +opm/core/simulator/SimulatorTwophase.cpp \ +opm/core/transport/reorder/TransportModelCompressibleTwophase.cpp \ +opm/core/transport/reorder/TransportModelInterface.cpp \ +opm/core/transport/reorder/TransportModelTwophase.cpp \ +opm/core/transport/reorder/nlsolvers.c \ +opm/core/transport/reorder/reordersequence.cpp \ +opm/core/transport/reorder/tarjan.c \ +opm/core/transport/spu_explicit.c \ +opm/core/transport/spu_implicit.c \ +opm/core/transport/transport_source.c \ +opm/core/utility/MonotCubicInterpolator.cpp \ +opm/core/utility/StopWatch.cpp \ +opm/core/utility/miscUtilities.cpp \ +opm/core/utility/miscUtilitiesBlackoil.cpp \ +opm/core/utility/parameters/Parameter.cpp \ +opm/core/utility/parameters/ParameterGroup.cpp \ +opm/core/utility/parameters/ParameterTools.cpp \ +opm/core/utility/parameters/ParameterXML.cpp \ +opm/core/utility/parameters/tinyxml/tinystr.cpp \ +opm/core/utility/parameters/tinyxml/tinyxml.cpp \ +opm/core/utility/parameters/tinyxml/tinyxmlerror.cpp \ +opm/core/utility/parameters/tinyxml/tinyxmlparser.cpp \ +opm/core/utility/writeVtkData.cpp \ +opm/core/vag_format/vag.cpp \ +opm/core/wells/InjectionSpecification.cpp \ +opm/core/wells/ProductionSpecification.cpp \ +opm/core/wells/WellCollection.cpp \ +opm/core/wells/WellsGroup.cpp \ opm/core/wells/WellsManager.cpp -nobase_include_HEADERS = \ -opm/core/GridAdapter.hpp \ -opm/core/GridManager.hpp \ -opm/core/eclipse/CornerpointChopper.hpp \ -opm/core/eclipse/EclipseGridInspector.hpp \ -opm/core/eclipse/EclipseGridParser.hpp \ -opm/core/eclipse/EclipseGridParserHelpers.hpp \ -opm/core/eclipse/EclipseUnits.hpp \ -opm/core/eclipse/SpecialEclipseFields.hpp \ -opm/core/fluid/BlackoilPropertiesBasic.hpp \ -opm/core/fluid/BlackoilPropertiesFromDeck.hpp \ -opm/core/fluid/BlackoilPropertiesInterface.hpp \ -opm/core/fluid/IncompPropertiesBasic.hpp \ -opm/core/fluid/IncompPropertiesFromDeck.hpp \ -opm/core/fluid/IncompPropertiesInterface.hpp \ -opm/core/fluid/PvtPropertiesBasic.hpp \ -opm/core/fluid/PvtPropertiesIncompFromDeck.hpp \ -opm/core/fluid/RockBasic.hpp \ -opm/core/fluid/RockCompressibility.hpp \ -opm/core/fluid/RockFromDeck.hpp \ -opm/core/fluid/SaturationPropsBasic.hpp \ -opm/core/fluid/SaturationPropsFromDeck.hpp \ -opm/core/fluid/SimpleFluid2p.hpp \ -opm/core/fluid/blackoil/BlackoilPhases.hpp \ -opm/core/fluid/blackoil/BlackoilPvtProperties.hpp \ -opm/core/fluid/blackoil/SinglePvtConstCompr.hpp \ -opm/core/fluid/blackoil/SinglePvtDead.hpp \ -opm/core/fluid/blackoil/SinglePvtInterface.hpp \ -opm/core/fluid/blackoil/SinglePvtLiveGas.hpp \ -opm/core/fluid/blackoil/SinglePvtLiveOil.hpp \ -opm/core/fluid/blackoil/phaseUsageFromDeck.hpp \ -opm/core/grid.h \ -opm/core/grid/cart_grid.h \ -opm/core/grid/cornerpoint_grid.h \ -opm/core/grid/cpgpreprocess/facetopology.h \ -opm/core/grid/cpgpreprocess/geometry.h \ -opm/core/grid/cpgpreprocess/grdecl.h \ -opm/core/grid/cpgpreprocess/preprocess.h \ -opm/core/grid/cpgpreprocess/readvector.hpp \ -opm/core/grid/cpgpreprocess/sparsetable.h \ -opm/core/grid/cpgpreprocess/uniquepoints.h \ -opm/core/linalg/LinearSolverFactory.hpp \ -opm/core/linalg/LinearSolverInterface.hpp \ -opm/core/linalg/blas_lapack.h \ -opm/core/linalg/sparse_sys.h \ -opm/core/newwells.h \ -opm/core/pressure/CompressibleTpfa.hpp \ -opm/core/pressure/FlowBCManager.hpp \ -opm/core/pressure/HybridPressureSolver.hpp \ -opm/core/pressure/IncompTpfa.hpp \ -opm/core/pressure/TPFACompressiblePressureSolver.hpp \ -opm/core/pressure/TPFAPressureSolver.hpp \ -opm/core/pressure/flow_bc.h \ -opm/core/pressure/fsh.h \ -opm/core/pressure/fsh_common_impl.h \ -opm/core/pressure/mimetic/hybsys.h \ -opm/core/pressure/mimetic/hybsys_global.h \ -opm/core/pressure/mimetic/mimetic.h \ -opm/core/pressure/msmfem/coarse_conn.h \ -opm/core/pressure/msmfem/coarse_sys.h \ -opm/core/pressure/msmfem/dfs.h \ -opm/core/pressure/msmfem/hash_set.h \ -opm/core/pressure/msmfem/ifsh_ms.h \ -opm/core/pressure/msmfem/partition.h \ -opm/core/pressure/tpfa/cfs_tpfa.h \ -opm/core/pressure/tpfa/cfs_tpfa_residual.h \ -opm/core/pressure/tpfa/compr_bc.h \ -opm/core/pressure/tpfa/compr_quant.h \ -opm/core/pressure/tpfa/compr_quant_general.h \ -opm/core/pressure/tpfa/compr_source.h \ -opm/core/pressure/tpfa/ifs_tpfa.h \ -opm/core/pressure/tpfa/trans_tpfa.h \ -opm/core/simulator/BlackoilState.hpp \ -opm/core/simulator/SimulatorReport.hpp \ -opm/core/simulator/SimulatorTimer.hpp \ -opm/core/simulator/SimulatorTwophase.hpp \ -opm/core/simulator/TwophaseState.hpp \ -opm/core/simulator/WellState.hpp \ -opm/core/transport/CSRMatrixBlockAssembler.hpp \ -opm/core/transport/CSRMatrixUmfpackSolver.hpp \ -opm/core/transport/GravityColumnSolver.hpp \ -opm/core/transport/GravityColumnSolver_impl.hpp \ -opm/core/transport/ImplicitAssembly.hpp \ -opm/core/transport/ImplicitTransport.hpp \ -opm/core/transport/JacobianSystem.hpp \ -opm/core/transport/NormSupport.hpp \ -opm/core/transport/SimpleFluid2pWrapper.hpp \ -opm/core/transport/SinglePointUpwindTwoPhase.hpp \ -opm/core/transport/reorder/TransportModelCompressibleTwophase.hpp \ -opm/core/transport/reorder/TransportModelInterface.hpp \ -opm/core/transport/reorder/TransportModelTwophase.hpp \ -opm/core/transport/reorder/nlsolvers.h \ -opm/core/transport/reorder/reordersequence.h \ -opm/core/transport/reorder/tarjan.h \ -opm/core/transport/spu_explicit.h \ -opm/core/transport/spu_implicit.h \ -opm/core/transport/transport_source.h \ -opm/core/utility/Average.hpp \ -opm/core/utility/ColumnExtract.hpp \ -opm/core/utility/ErrorMacros.hpp \ -opm/core/utility/Factory.hpp \ -opm/core/utility/MonotCubicInterpolator.hpp \ -opm/core/utility/RootFinders.hpp \ -opm/core/utility/SparseTable.hpp \ -opm/core/utility/SparseVector.hpp \ -opm/core/utility/StopWatch.hpp \ -opm/core/utility/UniformTableLinear.hpp \ -opm/core/utility/Units.hpp \ -opm/core/utility/buildUniformMonotoneTable.hpp \ -opm/core/utility/initState.hpp \ -opm/core/utility/initState_impl.hpp \ -opm/core/utility/linInt.hpp \ -opm/core/utility/linearInterpolation.hpp \ -opm/core/utility/miscUtilities.hpp \ -opm/core/utility/miscUtilitiesBlackoil.hpp \ -opm/core/utility/parameters/Parameter.hpp \ -opm/core/utility/parameters/ParameterGroup.hpp \ -opm/core/utility/parameters/ParameterGroup_impl.hpp \ -opm/core/utility/parameters/ParameterMapItem.hpp \ -opm/core/utility/parameters/ParameterRequirement.hpp \ -opm/core/utility/parameters/ParameterStrings.hpp \ -opm/core/utility/parameters/ParameterTools.hpp \ -opm/core/utility/parameters/ParameterXML.hpp \ -opm/core/utility/parameters/tinyxml/tinystr.h \ -opm/core/utility/parameters/tinyxml/tinyxml.h \ -opm/core/utility/writeVtkData.hpp \ -opm/core/vag_format/vag.hpp \ -opm/core/well.h \ -opm/core/wells/InjectionSpecification.hpp \ -opm/core/wells/ProductionSpecification.hpp \ -opm/core/wells/WellCollection.hpp \ -opm/core/wells/WellsGroup.hpp \ +nobase_include_HEADERS = \ +opm/core/GridAdapter.hpp \ +opm/core/GridManager.hpp \ +opm/core/eclipse/CornerpointChopper.hpp \ +opm/core/eclipse/EclipseGridInspector.hpp \ +opm/core/eclipse/EclipseGridParser.hpp \ +opm/core/eclipse/EclipseGridParserHelpers.hpp \ +opm/core/eclipse/EclipseUnits.hpp \ +opm/core/eclipse/SpecialEclipseFields.hpp \ +opm/core/fluid/BlackoilPropertiesBasic.hpp \ +opm/core/fluid/BlackoilPropertiesFromDeck.hpp \ +opm/core/fluid/BlackoilPropertiesInterface.hpp \ +opm/core/fluid/IncompPropertiesBasic.hpp \ +opm/core/fluid/IncompPropertiesFromDeck.hpp \ +opm/core/fluid/IncompPropertiesInterface.hpp \ +opm/core/fluid/PvtPropertiesBasic.hpp \ +opm/core/fluid/PvtPropertiesIncompFromDeck.hpp \ +opm/core/fluid/RockBasic.hpp \ +opm/core/fluid/RockCompressibility.hpp \ +opm/core/fluid/RockFromDeck.hpp \ +opm/core/fluid/SaturationPropsBasic.hpp \ +opm/core/fluid/SaturationPropsFromDeck.hpp \ +opm/core/fluid/SimpleFluid2p.hpp \ +opm/core/fluid/blackoil/BlackoilPhases.hpp \ +opm/core/fluid/blackoil/BlackoilPvtProperties.hpp \ +opm/core/fluid/blackoil/SinglePvtConstCompr.hpp \ +opm/core/fluid/blackoil/SinglePvtDead.hpp \ +opm/core/fluid/blackoil/SinglePvtInterface.hpp \ +opm/core/fluid/blackoil/SinglePvtLiveGas.hpp \ +opm/core/fluid/blackoil/SinglePvtLiveOil.hpp \ +opm/core/fluid/blackoil/phaseUsageFromDeck.hpp \ +opm/core/grid.h \ +opm/core/grid/cart_grid.h \ +opm/core/grid/cornerpoint_grid.h \ +opm/core/grid/cpgpreprocess/facetopology.h \ +opm/core/grid/cpgpreprocess/geometry.h \ +opm/core/grid/cpgpreprocess/grdecl.h \ +opm/core/grid/cpgpreprocess/preprocess.h \ +opm/core/grid/cpgpreprocess/readvector.hpp \ +opm/core/grid/cpgpreprocess/sparsetable.h \ +opm/core/grid/cpgpreprocess/uniquepoints.h \ +opm/core/linalg/LinearSolverFactory.hpp \ +opm/core/linalg/LinearSolverInterface.hpp \ +opm/core/linalg/blas_lapack.h \ +opm/core/linalg/sparse_sys.h \ +opm/core/newwells.h \ +opm/core/pressure/CompressibleTpfa.hpp \ +opm/core/pressure/FlowBCManager.hpp \ +opm/core/pressure/HybridPressureSolver.hpp \ +opm/core/pressure/IncompTpfa.hpp \ +opm/core/pressure/TPFACompressiblePressureSolver.hpp \ +opm/core/pressure/TPFAPressureSolver.hpp \ +opm/core/pressure/flow_bc.h \ +opm/core/pressure/fsh.h \ +opm/core/pressure/fsh_common_impl.h \ +opm/core/pressure/mimetic/hybsys.h \ +opm/core/pressure/mimetic/hybsys_global.h \ +opm/core/pressure/mimetic/mimetic.h \ +opm/core/pressure/msmfem/coarse_conn.h \ +opm/core/pressure/msmfem/coarse_sys.h \ +opm/core/pressure/msmfem/dfs.h \ +opm/core/pressure/msmfem/hash_set.h \ +opm/core/pressure/msmfem/ifsh_ms.h \ +opm/core/pressure/msmfem/partition.h \ +opm/core/pressure/tpfa/cfs_tpfa.h \ +opm/core/pressure/tpfa/cfs_tpfa_residual.h \ +opm/core/pressure/tpfa/compr_bc.h \ +opm/core/pressure/tpfa/compr_quant.h \ +opm/core/pressure/tpfa/compr_quant_general.h \ +opm/core/pressure/tpfa/compr_source.h \ +opm/core/pressure/tpfa/ifs_tpfa.h \ +opm/core/pressure/tpfa/trans_tpfa.h \ +opm/core/simulator/BlackoilState.hpp \ +opm/core/simulator/SimulatorReport.hpp \ +opm/core/simulator/SimulatorTimer.hpp \ +opm/core/simulator/SimulatorTwophase.hpp \ +opm/core/simulator/TwophaseState.hpp \ +opm/core/simulator/WellState.hpp \ +opm/core/transport/CSRMatrixBlockAssembler.hpp \ +opm/core/transport/CSRMatrixUmfpackSolver.hpp \ +opm/core/transport/GravityColumnSolver.hpp \ +opm/core/transport/GravityColumnSolver_impl.hpp \ +opm/core/transport/ImplicitAssembly.hpp \ +opm/core/transport/ImplicitTransport.hpp \ +opm/core/transport/JacobianSystem.hpp \ +opm/core/transport/NormSupport.hpp \ +opm/core/transport/SimpleFluid2pWrapper.hpp \ +opm/core/transport/SinglePointUpwindTwoPhase.hpp \ +opm/core/transport/reorder/TransportModelCompressibleTwophase.hpp \ +opm/core/transport/reorder/TransportModelInterface.hpp \ +opm/core/transport/reorder/TransportModelTwophase.hpp \ +opm/core/transport/reorder/nlsolvers.h \ +opm/core/transport/reorder/reordersequence.h \ +opm/core/transport/reorder/tarjan.h \ +opm/core/transport/spu_explicit.h \ +opm/core/transport/spu_implicit.h \ +opm/core/transport/transport_source.h \ +opm/core/utility/Average.hpp \ +opm/core/utility/ColumnExtract.hpp \ +opm/core/utility/ErrorMacros.hpp \ +opm/core/utility/Factory.hpp \ +opm/core/utility/MonotCubicInterpolator.hpp \ +opm/core/utility/RootFinders.hpp \ +opm/core/utility/SparseTable.hpp \ +opm/core/utility/SparseVector.hpp \ +opm/core/utility/StopWatch.hpp \ +opm/core/utility/UniformTableLinear.hpp \ +opm/core/utility/Units.hpp \ +opm/core/utility/buildUniformMonotoneTable.hpp \ +opm/core/utility/initState.hpp \ +opm/core/utility/initState_impl.hpp \ +opm/core/utility/linInt.hpp \ +opm/core/utility/linearInterpolation.hpp \ +opm/core/utility/miscUtilities.hpp \ +opm/core/utility/miscUtilitiesBlackoil.hpp \ +opm/core/utility/parameters/Parameter.hpp \ +opm/core/utility/parameters/ParameterGroup.hpp \ +opm/core/utility/parameters/ParameterGroup_impl.hpp \ +opm/core/utility/parameters/ParameterMapItem.hpp \ +opm/core/utility/parameters/ParameterRequirement.hpp \ +opm/core/utility/parameters/ParameterStrings.hpp \ +opm/core/utility/parameters/ParameterTools.hpp \ +opm/core/utility/parameters/ParameterXML.hpp \ +opm/core/utility/parameters/tinyxml/tinystr.h \ +opm/core/utility/parameters/tinyxml/tinyxml.h \ +opm/core/utility/writeVtkData.hpp \ +opm/core/vag_format/vag.hpp \ +opm/core/well.h \ +opm/core/wells/InjectionSpecification.hpp \ +opm/core/wells/ProductionSpecification.hpp \ +opm/core/wells/WellCollection.hpp \ +opm/core/wells/WellsGroup.hpp \ opm/core/wells/WellsManager.hpp # ---------------------------------------------------------------------- # Optional library constituents. if UMFPACK -libopmcore_la_SOURCES += \ -opm/core/linalg/call_umfpack.c \ +libopmcore_la_SOURCES += \ +opm/core/linalg/call_umfpack.c \ opm/core/linalg/LinearSolverUmfpack.cpp -nobase_include_HEADERS += \ -opm/core/linalg/call_umfpack.h \ +nobase_include_HEADERS += \ +opm/core/linalg/call_umfpack.h \ opm/core/linalg/LinearSolverUmfpack.hpp endif if DUNE_ISTL -libopmcore_la_SOURCES += \ +libopmcore_la_SOURCES += \ opm/core/linalg/LinearSolverIstl.cpp -nobase_include_HEADERS += \ +nobase_include_HEADERS += \ opm/core/linalg/LinearSolverIstl.hpp endif if BUILD_AGMG -libopmcore_la_SOURCES += \ -$(AGMG_SRCDIR)/dagmg.f90 \ -$(AGMG_SRCDIR)/dagmg_mumps.f90 \ +libopmcore_la_SOURCES += \ +$(AGMG_SRCDIR)/dagmg.f90 \ +$(AGMG_SRCDIR)/dagmg_mumps.f90 \ opm/core/linalg/LinearSolverAGMG.cpp -nobase_include_HEADERS += \ +nobase_include_HEADERS += \ opm/core/linalg/LinearSolverAGMG.hpp -libopmcore_la_LDFLAGS += \ +libopmcore_la_LDFLAGS += \ $(FCLIBS) endif diff --git a/configure.ac b/configure.ac index 7f82ebcc..9ed9cacd 100644 --- a/configure.ac +++ b/configure.ac @@ -78,6 +78,59 @@ m4_ifdef([AM_COND_IF], UMFPACK support is disabled.])]) ]) +#----------------------------------------------------------------- +# Support for ERT configuration in the OPM build process. The +# configuration is unfortunately not really functional :-(. +# +# Define the option --with-ert=/path/to/ert/root which can be passed +# to the configure script. If we pass --with-ert=no (the default) +# support for use of ert libraries will not be added built in; +# otherwise we will build support for ERT. +# + +# The argument given to the --with-ert option will be interpreted as +# the root path of a ert installation, and the build process will +# expect to find the ert libraries in $with_ert/lib and the header +# files in $with_ert/include. There are no check for actually finding +# the required libraries and headers, and support for ert could in +# principle be configured as: +# +# configure --with-ert=yes CPPFLAGS=-I/path/to/ert/include LDFLAGS=-L/path/to/ert/lib + +AC_ARG_WITH(ert, [AS_HELP_STRING([--with-ert=], [Use ERT libraries])], [], [with_ert=no]) + +AM_CONDITIONAL([HAVE_ERT], + [test "x$ert" != "xno"]) + +# The purpose of this macro was to test if the WITH_ERT conditional +# was true, and in that case the statements: +# +# AC_SUBST([ERT_ROOT],["$with_ert"]) +# AC_DEFINE([HAVE_ERT],1,[Are the ERT libraries available]) +# +# should be invoked - but the if construction does not work, and at +# the bottom of the configuration the two statements are invoked +# unconditionally (i.e. in the end the build will be with ert +# anyway). I will award anyone who can fix this a real bear :-) - +# Joakim. +m4_ifdef([AM_COND_IF], + [AM_COND_IF([HAVE_ERT], [AC_SUBST([ERT_ROOT],["$with_ert"])], []) +]) + +AC_SUBST([ERT_ROOT],["$with_ert"]) +AC_DEFINE(HAVE_ERT,1,[Are the ERT libraries available for reading and writing ECLIPSE files.]) + +# In addition to what is present in this script ERT support is further +# configured through: +# +# o The ERT_LDFLAGS and ERT_CPPFLAGS configured in the Makefile.am +# template. +# +# o The config.h file will define the symbol HAVE_ERT if ert is built into +# the current installation. +#----------------------------------------------------------------- + + AC_CONFIG_FILES([ Makefile diff --git a/examples/Makefile.am b/examples/Makefile.am index 7f165295..b2887f93 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -1,12 +1,15 @@ # Build-time flags needed to form example programs -AM_CPPFLAGS = \ --I$(top_srcdir) \ -$(BOOST_CPPFLAGS) +ERT_INCLUDE_PATH = $(ERT_ROOT)/include + +AM_CPPFLAGS = \ +-I$(top_srcdir) \ +$(BOOST_CPPFLAGS) \ +-I$(ERT_INCLUDE_PATH) # All targets link to the library -LDADD = \ -$(top_builddir)/libopmcore.la \ -$(BOOST_FILESYSTEM_LIB) \ +LDADD = \ +$(top_builddir)/libopmcore.la \ +$(BOOST_FILESYSTEM_LIB) \ $(BOOST_SYSTEM_LIB) # ---------------------------------------------------------------------- @@ -14,11 +17,11 @@ $(BOOST_SYSTEM_LIB) # # Please keep the list sorted. -noinst_PROGRAMS = \ -refine_wells \ -scaneclipsedeck \ -sim_2p_incomp_reorder \ -sim_wateroil \ +noinst_PROGRAMS = \ +refine_wells \ +scaneclipsedeck \ +sim_2p_incomp_reorder \ +sim_wateroil \ wells_example # ---------------------------------------------------------------------- @@ -40,7 +43,7 @@ if UMFPACK noinst_PROGRAMS += spu_2p spu_2p_SOURCES = spu_2p.cpp -spu_2p_LDADD = \ -$(LDADD) \ +spu_2p_LDADD = \ +$(LDADD) \ $(LAPACK_LIBS) $(BLAS_LIBS) $(LIBS) $(FLIBS) endif diff --git a/tests/Makefile.am b/tests/Makefile.am index 99eb79d9..ae4ee69d 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,27 +1,30 @@ -AM_CPPFLAGS = \ --I$(top_srcdir) \ -$(BOOST_CPPFLAGS) +ERT_INCLUDE_PATH = $(ERT_ROOT)/include + +AM_CPPFLAGS = \ +-I$(top_srcdir) \ +$(BOOST_CPPFLAGS) \ +-I$(ERT_INCLUDE_PATH) LDFLAGS = $(BOOST_LDFLAGS) -LDADD = $(top_builddir)/libopmcore.la +LDADD = $(top_builddir)/libopmcore.la -noinst_PROGRAMS = \ -bo_resprop_test \ -monotcubicinterpolator_test \ -param_test \ -sparsetable_test \ -sparsevector_test \ -test_cartgrid \ -test_column_extract \ -test_lapack \ -test_read_vag \ -test_readpolymer \ -test_readvector \ -test_sf2p \ -test_writeVtkData \ +noinst_PROGRAMS = \ +bo_resprop_test \ +monotcubicinterpolator_test \ +param_test \ +sparsetable_test \ +sparsevector_test \ +test_cartgrid \ +test_column_extract \ +test_lapack \ +test_read_vag \ +test_readpolymer \ +test_readvector \ +test_sf2p \ +test_writeVtkData \ unit_test @@ -69,3 +72,9 @@ if BUILD_AGMG noinst_PROGRAMS += test_agmg test_agmg_SOURCES = test_agmg.cpp endif + + +if HAVE_ERT +noinst_PROGRAMS += test_ert +test_ert_SOURCES = test_ert.cpp +endif \ No newline at end of file diff --git a/tests/test_ert.cpp b/tests/test_ert.cpp new file mode 100644 index 00000000..d2921f67 --- /dev/null +++ b/tests/test_ert.cpp @@ -0,0 +1,261 @@ +/* + 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 . +*/ + + +#include "config.h" +#include +#include +#include +#include +#include +#include +#include +#include + + +#include + +using namespace std; + + + +void cell_nodes(const UnstructuredGrid * c_grid , int cell , std::vector& nodes) { + int face_offset = c_grid->cell_facepos[cell]; + int num_faces = c_grid->cell_facepos[cell + 1] - face_offset; + + nodes.clear(); + //printf("cell: %d \n",cell); + for (int iface = 0; iface < num_faces; iface++) { + int face = c_grid->cell_faces[ face_offset + iface]; + //printf("face[%d] = %d \n",iface , face ); + + { + int node_offset = c_grid->face_nodepos[ face ]; + int num_nodes = c_grid->face_nodepos[ face + 1] - node_offset; + for (int inode = 0; inode < num_nodes; inode++) { + int node = c_grid->face_nodes[ inode + node_offset ]; + //printf(" node[%d] = %d \n",inode , node); + nodes.push_back( node ); + } + } + } + + { + /*for (int i =0; i < nodes.size(); i++) + std::cout << nodes[i] << " "; + std::cout << "\n"; + */ + sort( nodes.begin() , nodes.end()); + /*for (int i =0; i < nodes.size(); i++) + std::cout << nodes[i] << " "; + std::cout << "\n"; + */ + unique( nodes.begin() , nodes.end() ); + /*for (int i =0; i < nodes.size(); i++) + std::cout << nodes[i] << " "; + std::cout << "\n"; + */ + nodes.resize( 8 ); + /*for (int i =0; i < nodes.size(); i++) + std::cout << nodes[i] << " "; + std::cout << "\n"; + */ + } +} + + + +void eclExport(Opm::GridManager& grid) { + const UnstructuredGrid * c_grid = grid.c_grid(); + + printf("dimensions : %d \n",c_grid->dimensions); + printf("number of cells : %d \n",c_grid->number_of_cells); + printf("number of nodes : %d \n",c_grid->number_of_nodes); + printf("number of faces : %d \n",c_grid->number_of_faces); + printf("length(face_nodes) : %d \n",c_grid->face_nodepos[ c_grid->number_of_faces ]); + printf("cartdims : %d %d %d \n", + c_grid->cartdims[0] , + c_grid->cartdims[1] , + c_grid->cartdims[2]); + + printf("global_cell : %d %d %d %d %d\n", + c_grid->global_cell[0] , + c_grid->global_cell[1] , + c_grid->global_cell[2] , + c_grid->global_cell[3] , + c_grid->global_cell[4]); + + { + std::vector nodes; + cell_nodes( c_grid , 10 , nodes ); + cell_nodes( c_grid , 15 , nodes ); + cell_nodes( c_grid , 20 , nodes ); + cell_nodes( c_grid , 25 , nodes ); + } + + { + ecl_grid_type * ecl_grid; + int num_coords = c_grid->number_of_cells; + int coords_size = 4; + int nx = c_grid->cartdims[0]; + int ny = c_grid->cartdims[1]; + int nz = c_grid->cartdims[2]; + + int ** coords; + float ** corners; + float * mapaxes = NULL; + std::vector nodes; + + corners = (float **) malloc( num_coords * sizeof * corners ); + coords = (int **) malloc( num_coords * sizeof * coords ); + + { + int c; + for (c=0; c < num_coords; c++) { + corners[c] = (float *) malloc( 24 * sizeof * corners[c] ); + coords[c] = (int *) malloc( coords_size * sizeof * coords[c] ); + } + + for (c=0; c < num_coords; c++) { + cell_nodes( c_grid , c , nodes ); + for (int p=0; p < 8; p++) { + int n = nodes[p]; + for (int d=0; d < c_grid->dimensions; d++) + corners[c][3*p + d] = c_grid->node_coordinates[ c_grid->dimensions * n + d ]; + } + + { + int i,j,k; + { + int g = c_grid->global_cell[ c ]; + k = g / nx*ny; g -= k * nx*ny; + j = g / nx; g -= j * nx; + i = g; + } + + coords[c][0] = i + 1; + coords[c][1] = j + 1; + coords[c][2] = k + 1; + coords[c][3] = c_grid->global_cell[ c ] + 1; + } + } + } + + ecl_grid = ecl_grid_alloc( "/private/joaho/ERT/NR/libenkf/src/Gurbat/EXAMPLE_01_BASE.EGRID" ); + printf("Grid loaded ... \n"); + ecl_grid_free( ecl_grid ); + + printf("Grid discarded ... \n"); + + ecl_grid = ecl_grid_alloc_GRID_data( num_coords , nx , ny , nz , coords_size , coords , corners , NULL ); + ecl_grid_fwrite_GRID( ecl_grid , "/tmp/test.GRID" ); + + { + FILE * stream = fopen( "/tmp/test.grdecl" , "w"); + ecl_grid_fprintf_grdecl( ecl_grid , stream ); + fclose( stream ); + } + + ecl_grid_free( ecl_grid ); + + { + for (int c=0; c < num_coords; c++) { + free(corners[c]); + free(coords[c]); + } + } + free( corners ); + free( coords ); + } +} + + + +/* + + #ifdef HAVE_ERT +ecl_grid_type * create_ecl_grid( const struct UnstructuredGrid * g) { + int num_coords = g->number_of_cells; + int nx = g->cartdims[0]; + int ny = g->cartdims[1]; + int nz = g->cartdims[2]; + int coords_size = 4; + int ** coords; + float ** corners; + float * mapaxes = NULL; + + corners = malloc( num_coords * sizeof * corners ); + coords = malloc( num_coords * sizeof * coords ); + + { + for (int c=0; c < num_coords; c++) { + corners[c] = malloc( 24 * sizeof * corners[0] ); + coords[c] = malloc( coords_size * sizeof * coords[0] ); + } + } + + { + for (int k=0; k < nz; k++) { + for (int j=0; j < ny; j++) { + for (int i=0; i < nx; i++) { + int global_index = i + j*nx + k*nx*ny; + + coords[global_index][0] = i; + coords[global_index][1] = j; + coords[global_index][2] = k; + coords[global_index][3] = 1; + + } + } + } + } + { + for (int c=0; c < num_coords; c++) { + free(corners[c]); + free(coords[c]); + } + } + free( corners ); + free( coords ); +} +#endif + + + */ + +// struct grdecl : opm/core/grid/cpgpreprocess/preprocess.h +// struct processes_grid : opm/core/grid/cpgpreprocess/preprocess.h + + + +int main(int argc , char **argv) +{ + std::string filename( argv[1] ); + boost::scoped_ptr grid; + boost::scoped_ptr props; + Opm::EclipseGridParser eclParser(filename , false); + + //eclParser.saveEGRID_INIT("/tmp" , "OPM" ); + + grid.reset(new Opm::GridManager(eclParser)); + const int* gc = grid->c_grid()->global_cell; + std::vector global_cell(gc, gc + grid->c_grid()->number_of_cells); + + props.reset(new Opm::IncompPropertiesFromDeck(eclParser , global_cell)); +} From e8f1048b4652d8a0b692ffd151ac479df2bcad58 Mon Sep 17 00:00:00 2001 From: Joakim Hove Date: Wed, 27 Jun 2012 14:20:20 +0200 Subject: [PATCH 02/38] Merge fix in Makefile.am --- Makefile.am | 222 ---------------------------------------------------- 1 file changed, 222 deletions(-) diff --git a/Makefile.am b/Makefile.am index 22bc09ec..583e67ff 100644 --- a/Makefile.am +++ b/Makefile.am @@ -42,7 +42,6 @@ $(ERT_LDFLAGS) $(LAPACK_LIBS) $(BLAS_LIBS) $(LIBS) $(FLIBS) # # Please try to keep the list sorted. -<<<<<<< HEAD libopmcore_la_SOURCES = \ opm/core/GridManager.cpp \ opm/core/eclipse/EclipseGridInspector.cpp \ @@ -266,227 +265,6 @@ opm/core/wells/InjectionSpecification.hpp \ opm/core/wells/ProductionSpecification.hpp \ opm/core/wells/WellCollection.hpp \ opm/core/wells/WellsGroup.hpp \ -======= -libopmcore_la_SOURCES = \ -opm/core/GridManager.cpp \ -opm/core/eclipse/EclipseGridInspector.cpp \ -opm/core/eclipse/EclipseGridParser.cpp \ -opm/core/fluid/BlackoilPropertiesBasic.cpp \ -opm/core/fluid/BlackoilPropertiesFromDeck.cpp \ -opm/core/fluid/IncompPropertiesBasic.cpp \ -opm/core/fluid/IncompPropertiesFromDeck.cpp \ -opm/core/fluid/PvtPropertiesBasic.cpp \ -opm/core/fluid/PvtPropertiesIncompFromDeck.cpp \ -opm/core/fluid/RockBasic.cpp \ -opm/core/fluid/RockCompressibility.cpp \ -opm/core/fluid/RockFromDeck.cpp \ -opm/core/fluid/SaturationPropsBasic.cpp \ -opm/core/fluid/SaturationPropsFromDeck.cpp \ -opm/core/fluid/blackoil/BlackoilPvtProperties.cpp \ -opm/core/fluid/blackoil/SinglePvtDead.cpp \ -opm/core/fluid/blackoil/SinglePvtInterface.cpp \ -opm/core/fluid/blackoil/SinglePvtLiveGas.cpp \ -opm/core/fluid/blackoil/SinglePvtLiveOil.cpp \ -opm/core/grid.c \ -opm/core/grid/cart_grid.c \ -opm/core/grid/cornerpoint_grid.c \ -opm/core/grid/cpgpreprocess/facetopology.c \ -opm/core/grid/cpgpreprocess/geometry.c \ -opm/core/grid/cpgpreprocess/preprocess.c \ -opm/core/grid/cpgpreprocess/uniquepoints.c \ -opm/core/linalg/LinearSolverFactory.cpp \ -opm/core/linalg/LinearSolverInterface.cpp \ -opm/core/linalg/sparse_sys.c \ -opm/core/newwells.c \ -opm/core/pressure/CompressibleTpfa.cpp \ -opm/core/pressure/FlowBCManager.cpp \ -opm/core/pressure/IncompTpfa.cpp \ -opm/core/pressure/cfsh.c \ -opm/core/pressure/flow_bc.c \ -opm/core/pressure/fsh.c \ -opm/core/pressure/fsh_common_impl.c \ -opm/core/pressure/ifsh.c \ -opm/core/pressure/mimetic/hybsys.c \ -opm/core/pressure/mimetic/hybsys_global.c \ -opm/core/pressure/mimetic/mimetic.c \ -opm/core/pressure/msmfem/coarse_conn.c \ -opm/core/pressure/msmfem/coarse_sys.c \ -opm/core/pressure/msmfem/dfs.c \ -opm/core/pressure/msmfem/hash_set.c \ -opm/core/pressure/msmfem/ifsh_ms.c \ -opm/core/pressure/msmfem/partition.c \ -opm/core/pressure/tpfa/cfs_tpfa.c \ -opm/core/pressure/tpfa/cfs_tpfa_residual.c \ -opm/core/pressure/tpfa/compr_bc.c \ -opm/core/pressure/tpfa/compr_quant.c \ -opm/core/pressure/tpfa/compr_quant_general.c \ -opm/core/pressure/tpfa/compr_source.c \ -opm/core/pressure/tpfa/ifs_tpfa.c \ -opm/core/pressure/tpfa/trans_tpfa.c \ -opm/core/pressure/well.c \ -opm/core/simulator/SimulatorReport.cpp \ -opm/core/simulator/SimulatorTimer.cpp \ -opm/core/simulator/SimulatorTwophase.cpp \ -opm/core/transport/reorder/TransportModelCompressibleTwophase.cpp \ -opm/core/transport/reorder/TransportModelInterface.cpp \ -opm/core/transport/reorder/TransportModelTwophase.cpp \ -opm/core/transport/reorder/nlsolvers.c \ -opm/core/transport/reorder/reordersequence.cpp \ -opm/core/transport/reorder/tarjan.c \ -opm/core/transport/spu_explicit.c \ -opm/core/transport/spu_implicit.c \ -opm/core/transport/transport_source.c \ -opm/core/utility/MonotCubicInterpolator.cpp \ -opm/core/utility/StopWatch.cpp \ -opm/core/utility/miscUtilities.cpp \ -opm/core/utility/miscUtilitiesBlackoil.cpp \ -opm/core/utility/parameters/Parameter.cpp \ -opm/core/utility/parameters/ParameterGroup.cpp \ -opm/core/utility/parameters/ParameterTools.cpp \ -opm/core/utility/parameters/ParameterXML.cpp \ -opm/core/utility/parameters/tinyxml/tinystr.cpp \ -opm/core/utility/parameters/tinyxml/tinyxml.cpp \ -opm/core/utility/parameters/tinyxml/tinyxmlerror.cpp \ -opm/core/utility/parameters/tinyxml/tinyxmlparser.cpp \ -opm/core/utility/writeVtkData.cpp \ -opm/core/vag_format/vag.cpp \ -opm/core/wells/InjectionSpecification.cpp \ -opm/core/wells/ProductionSpecification.cpp \ -opm/core/wells/WellCollection.cpp \ -opm/core/wells/WellsGroup.cpp \ -opm/core/wells/WellsManager.cpp - -nobase_include_HEADERS = \ -opm/core/GridAdapter.hpp \ -opm/core/GridManager.hpp \ -opm/core/eclipse/CornerpointChopper.hpp \ -opm/core/eclipse/EclipseGridInspector.hpp \ -opm/core/eclipse/EclipseGridParser.hpp \ -opm/core/eclipse/EclipseGridParserHelpers.hpp \ -opm/core/eclipse/EclipseUnits.hpp \ -opm/core/eclipse/SpecialEclipseFields.hpp \ -opm/core/fluid/BlackoilPropertiesBasic.hpp \ -opm/core/fluid/BlackoilPropertiesFromDeck.hpp \ -opm/core/fluid/BlackoilPropertiesInterface.hpp \ -opm/core/fluid/IncompPropertiesBasic.hpp \ -opm/core/fluid/IncompPropertiesFromDeck.hpp \ -opm/core/fluid/IncompPropertiesInterface.hpp \ -opm/core/fluid/PvtPropertiesBasic.hpp \ -opm/core/fluid/PvtPropertiesIncompFromDeck.hpp \ -opm/core/fluid/RockBasic.hpp \ -opm/core/fluid/RockCompressibility.hpp \ -opm/core/fluid/RockFromDeck.hpp \ -opm/core/fluid/SaturationPropsBasic.hpp \ -opm/core/fluid/SaturationPropsFromDeck.hpp \ -opm/core/fluid/SimpleFluid2p.hpp \ -opm/core/fluid/blackoil/BlackoilPhases.hpp \ -opm/core/fluid/blackoil/BlackoilPvtProperties.hpp \ -opm/core/fluid/blackoil/SinglePvtConstCompr.hpp \ -opm/core/fluid/blackoil/SinglePvtDead.hpp \ -opm/core/fluid/blackoil/SinglePvtInterface.hpp \ -opm/core/fluid/blackoil/SinglePvtLiveGas.hpp \ -opm/core/fluid/blackoil/SinglePvtLiveOil.hpp \ -opm/core/fluid/blackoil/phaseUsageFromDeck.hpp \ -opm/core/grid.h \ -opm/core/grid/cart_grid.h \ -opm/core/grid/cornerpoint_grid.h \ -opm/core/grid/cpgpreprocess/facetopology.h \ -opm/core/grid/cpgpreprocess/geometry.h \ -opm/core/grid/cpgpreprocess/grdecl.h \ -opm/core/grid/cpgpreprocess/preprocess.h \ -opm/core/grid/cpgpreprocess/uniquepoints.h \ -opm/core/linalg/LinearSolverFactory.hpp \ -opm/core/linalg/LinearSolverInterface.hpp \ -opm/core/linalg/blas_lapack.h \ -opm/core/linalg/sparse_sys.h \ -opm/core/newwells.h \ -opm/core/pressure/CompressibleTpfa.hpp \ -opm/core/pressure/FlowBCManager.hpp \ -opm/core/pressure/HybridPressureSolver.hpp \ -opm/core/pressure/IncompTpfa.hpp \ -opm/core/pressure/TPFACompressiblePressureSolver.hpp \ -opm/core/pressure/TPFAPressureSolver.hpp \ -opm/core/pressure/flow_bc.h \ -opm/core/pressure/fsh.h \ -opm/core/pressure/fsh_common_impl.h \ -opm/core/pressure/mimetic/hybsys.h \ -opm/core/pressure/mimetic/hybsys_global.h \ -opm/core/pressure/mimetic/mimetic.h \ -opm/core/pressure/msmfem/coarse_conn.h \ -opm/core/pressure/msmfem/coarse_sys.h \ -opm/core/pressure/msmfem/dfs.h \ -opm/core/pressure/msmfem/hash_set.h \ -opm/core/pressure/msmfem/ifsh_ms.h \ -opm/core/pressure/msmfem/partition.h \ -opm/core/pressure/tpfa/cfs_tpfa.h \ -opm/core/pressure/tpfa/cfs_tpfa_residual.h \ -opm/core/pressure/tpfa/compr_bc.h \ -opm/core/pressure/tpfa/compr_quant.h \ -opm/core/pressure/tpfa/compr_quant_general.h \ -opm/core/pressure/tpfa/compr_source.h \ -opm/core/pressure/tpfa/ifs_tpfa.h \ -opm/core/pressure/tpfa/trans_tpfa.h \ -opm/core/simulator/BlackoilState.hpp \ -opm/core/simulator/SimulatorReport.hpp \ -opm/core/simulator/SimulatorTimer.hpp \ -opm/core/simulator/SimulatorTwophase.hpp \ -opm/core/simulator/TwophaseState.hpp \ -opm/core/simulator/WellState.hpp \ -opm/core/transport/CSRMatrixBlockAssembler.hpp \ -opm/core/transport/CSRMatrixUmfpackSolver.hpp \ -opm/core/transport/GravityColumnSolver.hpp \ -opm/core/transport/GravityColumnSolver_impl.hpp \ -opm/core/transport/ImplicitAssembly.hpp \ -opm/core/transport/ImplicitTransport.hpp \ -opm/core/transport/JacobianSystem.hpp \ -opm/core/transport/NormSupport.hpp \ -opm/core/transport/SimpleFluid2pWrapper.hpp \ -opm/core/transport/SinglePointUpwindTwoPhase.hpp \ -opm/core/transport/reorder/TransportModelCompressibleTwophase.hpp \ -opm/core/transport/reorder/TransportModelInterface.hpp \ -opm/core/transport/reorder/TransportModelTwophase.hpp \ -opm/core/transport/reorder/nlsolvers.h \ -opm/core/transport/reorder/reordersequence.h \ -opm/core/transport/reorder/tarjan.h \ -opm/core/transport/spu_explicit.h \ -opm/core/transport/spu_implicit.h \ -opm/core/transport/transport_source.h \ -opm/core/utility/Average.hpp \ -opm/core/utility/ColumnExtract.hpp \ -opm/core/utility/ErrorMacros.hpp \ -opm/core/utility/Factory.hpp \ -opm/core/utility/MonotCubicInterpolator.hpp \ -opm/core/utility/RootFinders.hpp \ -opm/core/utility/SparseTable.hpp \ -opm/core/utility/SparseVector.hpp \ -opm/core/utility/StopWatch.hpp \ -opm/core/utility/UniformTableLinear.hpp \ -opm/core/utility/Units.hpp \ -opm/core/utility/buildUniformMonotoneTable.hpp \ -opm/core/utility/initState.hpp \ -opm/core/utility/initState_impl.hpp \ -opm/core/utility/linInt.hpp \ -opm/core/utility/linearInterpolation.hpp \ -opm/core/utility/miscUtilities.hpp \ -opm/core/utility/miscUtilitiesBlackoil.hpp \ -opm/core/utility/parameters/Parameter.hpp \ -opm/core/utility/parameters/ParameterGroup.hpp \ -opm/core/utility/parameters/ParameterGroup_impl.hpp \ -opm/core/utility/parameters/ParameterMapItem.hpp \ -opm/core/utility/parameters/ParameterRequirement.hpp \ -opm/core/utility/parameters/ParameterStrings.hpp \ -opm/core/utility/parameters/ParameterTools.hpp \ -opm/core/utility/parameters/ParameterXML.hpp \ -opm/core/utility/parameters/tinyxml/tinystr.h \ -opm/core/utility/parameters/tinyxml/tinyxml.h \ -opm/core/utility/writeVtkData.hpp \ -opm/core/vag_format/vag.hpp \ -opm/core/well.h \ -opm/core/wells/InjectionSpecification.hpp \ -opm/core/wells/ProductionSpecification.hpp \ -opm/core/wells/WellCollection.hpp \ -opm/core/wells/WellsGroup.hpp \ ->>>>>>> master opm/core/wells/WellsManager.hpp # ---------------------------------------------------------------------- From bb066aa23beb8eea7c3c8e1560b1631f015a89eb Mon Sep 17 00:00:00 2001 From: Joakim Hove Date: Wed, 27 Jun 2012 20:20:05 +0200 Subject: [PATCH 03/38] Added functionality to save results in ECLIPSE format from ERT libraries. --- Makefile.am | 15 +- examples/spu_2p.cpp | 14 +- opm/core/GridManager.cpp | 66 ++---- opm/core/eclipse/EclipseGridParser.cpp | 259 ++++++++++++++++++++++- opm/core/eclipse/EclipseGridParser.hpp | 23 ++ opm/core/grid/cpgpreprocess/preprocess.h | 1 + opm/core/utility/writeECLData.cpp | 98 +++++++++ opm/core/utility/writeECLData.hpp | 47 ++++ tests/Makefile.am | 1 - 9 files changed, 468 insertions(+), 56 deletions(-) create mode 100644 opm/core/utility/writeECLData.cpp create mode 100644 opm/core/utility/writeECLData.hpp diff --git a/Makefile.am b/Makefile.am index 583e67ff..06e98c1d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -15,7 +15,7 @@ lib_LTLIBRARIES = libopmcore.la # ERT related settings #if HAVE_ERT ERT_LIB_PATH = $(ERT_ROOT)/lib -ERT_LIBS = -leclxx -lecl -lgeometry -lutil -lpthread -lz -lgomp +ERT_LIBS = -lecl -lgeometry -lutil -lpthread -lz -lgomp ERT_LDFLAGS = -L$(ERT_LIB_PATH) $(ERT_LIBS) ERT_INCLUDE_PATH = $(ERT_ROOT)/include ERT_CPPFLAGS = -I$(ERT_INCLUDE_PATH) @@ -68,8 +68,6 @@ opm/core/grid/cornerpoint_grid.c \ opm/core/grid/cpgpreprocess/facetopology.c \ opm/core/grid/cpgpreprocess/geometry.c \ opm/core/grid/cpgpreprocess/preprocess.c \ -opm/core/grid/cpgpreprocess/readvector.cpp \ -opm/core/grid/cpgpreprocess/sparsetable.c \ opm/core/grid/cpgpreprocess/uniquepoints.c \ opm/core/linalg/LinearSolverFactory.cpp \ opm/core/linalg/LinearSolverInterface.cpp \ @@ -171,8 +169,6 @@ opm/core/grid/cpgpreprocess/facetopology.h \ opm/core/grid/cpgpreprocess/geometry.h \ opm/core/grid/cpgpreprocess/grdecl.h \ opm/core/grid/cpgpreprocess/preprocess.h \ -opm/core/grid/cpgpreprocess/readvector.hpp \ -opm/core/grid/cpgpreprocess/sparsetable.h \ opm/core/grid/cpgpreprocess/uniquepoints.h \ opm/core/linalg/LinearSolverFactory.hpp \ opm/core/linalg/LinearSolverInterface.hpp \ @@ -259,6 +255,7 @@ opm/core/utility/parameters/ParameterXML.hpp \ opm/core/utility/parameters/tinyxml/tinystr.h \ opm/core/utility/parameters/tinyxml/tinyxml.h \ opm/core/utility/writeVtkData.hpp \ +opm/core/utility/DataMap.hpp \ opm/core/vag_format/vag.hpp \ opm/core/well.h \ opm/core/wells/InjectionSpecification.hpp \ @@ -280,6 +277,14 @@ opm/core/linalg/call_umfpack.h \ opm/core/linalg/LinearSolverUmfpack.hpp endif +if HAVE_ERT +libopmcore_la_SOURCES += \ +opm/core/utility/writeECLData.cpp + +nobase_include_HEADERS += \ +opm/core/utility/writeECLData.hpp +endif + if DUNE_ISTL libopmcore_la_SOURCES += \ diff --git a/examples/spu_2p.cpp b/examples/spu_2p.cpp index 69697378..ca05b424 100644 --- a/examples/spu_2p.cpp +++ b/examples/spu_2p.cpp @@ -94,14 +94,19 @@ #include +#ifdef HAVE_ERT +#include +#endif + static void outputState(const UnstructuredGrid& grid, const Opm::TwophaseState& state, - const int step, + const Opm::SimulatorTimer& simtimer, const std::string& output_dir) { // Write data in VTK format. + int step = simtimer.currentStepNum(); std::ostringstream vtkfilename; vtkfilename << output_dir << "/output-" << std::setw(3) << std::setfill('0') << step << ".vtu"; std::ofstream vtkfile(vtkfilename.str().c_str()); @@ -115,6 +120,9 @@ static void outputState(const UnstructuredGrid& grid, Opm::estimateCellVelocity(grid, state.faceflux(), cell_velocity); dm["velocity"] = &cell_velocity; Opm::writeVtkData(grid, dm, vtkfile); +#ifdef HAVE_ERT + Opm::writeECLData(grid , dm , simtimer , output_dir , "OPM" ); +#endif // Write data (not grid) in Matlab format for (Opm::DataMap::const_iterator it = dm.begin(); it != dm.end(); ++it) { @@ -532,7 +540,7 @@ main(int argc, char** argv) // Report timestep and (optionally) write state to disk. simtimer.report(std::cout); if (output && (simtimer.currentStepNum() % output_interval == 0)) { - outputState(*grid->c_grid(), state, simtimer.currentStepNum(), output_dir); + outputState(*grid->c_grid(), state, simtimer , output_dir); } // Solve pressure. @@ -701,7 +709,7 @@ main(int argc, char** argv) << "\n Transport time: " << ttime << std::endl; if (output) { - outputState(*grid->c_grid(), state, simtimer.currentStepNum(), output_dir); + outputState(*grid->c_grid(), state, simtimer, output_dir); outputWaterCut(watercut, output_dir); if (wells->c_wells()) { outputWellReport(wellreport, output_dir); diff --git a/opm/core/GridManager.cpp b/opm/core/GridManager.cpp index 16140a07..f84692ee 100644 --- a/opm/core/GridManager.cpp +++ b/opm/core/GridManager.cpp @@ -33,36 +33,14 @@ namespace Opm /// Construct a 3d corner-point grid from a deck. GridManager::GridManager(const Opm::EclipseGridParser& deck) { - // Extract data from deck. - const std::vector& zcorn = deck.getFloatingPointValue("ZCORN"); - const std::vector& coord = deck.getFloatingPointValue("COORD"); - const int* actnum = 0; - if (deck.hasField("ACTNUM")) { - actnum = &(deck.getIntegerValue("ACTNUM")[0]); - } - std::vector dims; - if (deck.hasField("DIMENS")) { - dims = deck.getIntegerValue("DIMENS"); - } else if (deck.hasField("SPECGRID")) { - dims = deck.getSPECGRID().dimensions; - } else { - THROW("Deck must have either DIMENS or SPECGRID."); - } - - // Collect in input struct for preprocessing. - struct grdecl grdecl; - grdecl.zcorn = &zcorn[0]; - grdecl.coord = &coord[0]; - grdecl.actnum = actnum; - grdecl.dims[0] = dims[0]; - grdecl.dims[1] = dims[1]; - grdecl.dims[2] = dims[2]; - - // Process grid. - ug_ = create_grid_cornerpoint(&grdecl, 0.0); - if (!ug_) { - THROW("Failed to construct grid."); - } + // Collect in input struct for preprocessing. + struct grdecl grdecl = deck.get_grdecl(); + + // Process grid. + ug_ = create_grid_cornerpoint(&grdecl, 0.0); + if (!ug_) { + THROW("Failed to construct grid."); + } } @@ -71,10 +49,10 @@ namespace Opm /// Construct a 2d cartesian grid with cells of unit size. GridManager::GridManager(int nx, int ny) { - ug_ = create_grid_cart2d(nx, ny); - if (!ug_) { - THROW("Failed to construct grid."); - } + ug_ = create_grid_cart2d(nx, ny); + if (!ug_) { + THROW("Failed to construct grid."); + } } @@ -83,10 +61,10 @@ namespace Opm /// Construct a 3d cartesian grid with cells of unit size. GridManager::GridManager(int nx, int ny, int nz) { - ug_ = create_grid_cart3d(nx, ny, nz); - if (!ug_) { - THROW("Failed to construct grid."); - } + ug_ = create_grid_cart3d(nx, ny, nz); + if (!ug_) { + THROW("Failed to construct grid."); + } } @@ -96,10 +74,10 @@ namespace Opm GridManager::GridManager(int nx, int ny, int nz, double dx, double dy, double dz) { - ug_ = create_grid_hexa3d(nx, ny, nz, dx, dy, dz); - if (!ug_) { - THROW("Failed to construct grid."); - } + ug_ = create_grid_hexa3d(nx, ny, nz, dx, dy, dz); + if (!ug_) { + THROW("Failed to construct grid."); + } } @@ -108,7 +86,7 @@ namespace Opm /// Destructor. GridManager::~GridManager() { - destroy_grid(ug_); + destroy_grid(ug_); } @@ -119,7 +97,7 @@ namespace Opm /// to make it clear that we are returning a C-compatible struct. const UnstructuredGrid* GridManager::c_grid() const { - return ug_; + return ug_; } diff --git a/opm/core/eclipse/EclipseGridParser.cpp b/opm/core/eclipse/EclipseGridParser.cpp index fd5f5ef5..d582a996 100644 --- a/opm/core/eclipse/EclipseGridParser.cpp +++ b/opm/core/eclipse/EclipseGridParser.cpp @@ -47,8 +47,18 @@ #include #include #include -#include #include +#include +#include + +#ifdef HAVE_ERT +#include +#include +#include +#include +#include +#include +#endif using namespace std; @@ -86,7 +96,7 @@ namespace EclipseKeywords string("MULTPV"), string("PRESSURE"), string("SGAS"), string("SWAT"), string("SOIL"), string("RS"), string("DXV"), string("DYV"), string("DZV"), - string("DEPTHZ") + string("DEPTHZ"), string("MAPAXES") }; const int num_floating_fields = sizeof(floating_fields) / sizeof(floating_fields[0]); @@ -114,7 +124,7 @@ namespace EclipseKeywords const int num_special_fields = sizeof(special_fields) / sizeof(special_fields[0]); string ignore_with_data[] = - { string("MAPUNITS"), string("MAPAXES"), string("GRIDUNIT"), + { string("MAPUNITS"), string("GRIDUNIT"), string("NTG"), string("REGDIMS"), string("WELLDIMS"), string("NSTACK"), string("SATNUM"), string("RPTRST"), string("ROIP"), string("RWIP"), @@ -814,5 +824,248 @@ void EclipseGridParser::computeUnits() THROW("Unknown unit family " << unit_family); } } + + +struct grdecl EclipseGridParser::get_grdecl() const { + struct grdecl grdecl; + + // Extract data from deck. + const std::vector& zcorn = getFloatingPointValue("ZCORN"); + const std::vector& coord = getFloatingPointValue("COORD"); + const int* actnum = NULL; + if (hasField("ACTNUM")) { + actnum = &(getIntegerValue("ACTNUM")[0]); + } + + std::vector dims; + if (hasField("DIMENS")) { + dims = getIntegerValue("DIMENS"); + } else if (hasField("SPECGRID")) { + dims = getSPECGRID().dimensions; + } else { + THROW("Deck must have either DIMENS or SPECGRID."); + } + + // Collect in input struct for preprocessing. + + grdecl.zcorn = &zcorn[0]; + grdecl.coord = &coord[0]; + grdecl.actnum = actnum; + grdecl.dims[0] = dims[0]; + grdecl.dims[1] = dims[1]; + grdecl.dims[2] = dims[2]; + + if (hasField("MAPAXES")) { + const std::vector &mapaxes = getFloatingPointValue("MAPAXES"); + grdecl.mapaxes = &mapaxes[0]; + } else + grdecl.mapaxes = NULL; + + + return grdecl; +} + + +#ifdef HAVE_ERT +/* + This function will create a ecl_kw instance filled with the data + from input argument @keyword. The ecl_kw will get it's own copy of + the data. + + If the input type ecl_type == ECL_INT_TYPE the function will use the + getIntegerValue() method to get the keyword data, if ecl_type == + ECL_DOUBLE_TYPE || ECL_FLOAT_TYPE the getFloatingPointValue() + function is invoked. If ecl_type == ECL_FLOAT_TYPE the data will be + converted to when inserting into the ecl_kw. + + When the ecl_kw instance is no longer needed it should be discarded + with a call to ecl_kw_free( ). + + If you are asking for a non-existent field the function will return NULL +*/ + +ecl_kw_type * EclipseGridParser::newEclKW(const std::string &keyword , ecl_type_enum ecl_type) const { + ecl_kw_type * ecl_kw = NULL; + if (hasField(keyword)) { + if (ecl_type == ECL_INT_TYPE) { + std::vector data = getIntegerValue( keyword ); + ecl_kw = ecl_kw_alloc( keyword.c_str() , data.size() , ecl_type ); + ecl_kw_set_memcpy_data( ecl_kw , &data[0]); + } else { + std::vector data = getFloatingPointValue( keyword ); + if (ecl_type == ECL_DOUBLE_TYPE) { + ecl_kw = ecl_kw_alloc( keyword.c_str() , data.size() , ecl_type ); + ecl_kw_set_memcpy_data( ecl_kw , &data[0]); + } else if (ecl_type == ECL_FLOAT_TYPE) { + ecl_kw = ecl_kw_alloc( keyword.c_str() , data.size() , ecl_type ); + for (int i=0; i < data.size(); i++) + ecl_kw_iset_float( ecl_kw , i , data[i] ); + } + } + } + return ecl_kw; +} + + +/** + This function will extract the COORD, ZCORN, ACTNUM and optionaly + MAPAXES keywords from the eclipse deck and create an ecl_grid + instance. + + When you are finished working with the ecl_grid instance it should + be disposed with ecl_grid_free( ). +*/ + +ecl_grid_type * EclipseGridParser::newGrid( ) { + struct grdecl grdecl = get_grdecl(); + ecl_kw_type * coord_kw = newEclKW( COORD_KW , ECL_FLOAT_TYPE ); + ecl_kw_type * zcorn_kw = newEclKW( ZCORN_KW , ECL_FLOAT_TYPE ); + ecl_kw_type * actnum_kw = newEclKW( ACTNUM_KW , ECL_INT_TYPE ); + ecl_kw_type * mapaxes_kw = NULL; + + ecl_grid_type * grid ; + if (grdecl.mapaxes != NULL) + mapaxes_kw = newEclKW( MAPAXES_KW , ECL_FLOAT_TYPE ); + + grid = ecl_grid_alloc_GRDECL_kw( grdecl.dims[0] , grdecl.dims[1] , grdecl.dims[2] , zcorn_kw , coord_kw , actnum_kw , mapaxes_kw ); + + ecl_kw_free( coord_kw ); + ecl_kw_free( zcorn_kw ); + ecl_kw_free( actnum_kw ); + if (mapaxes_kw != NULL) + ecl_kw_free( mapaxes_kw ); + + return grid; +} + + + +/** + This function will save an EGRID file based on the COORD, ZCORN, + ACTNUM and optionally MAPAXES keywords included in the deck. + + This function creates the EGRID file without going through a + ecl_grid instance; this is obviously somewhat faster and less + memory demanding. Alternatively you can create a ecl_grid instance + and then subsequently store that grid as an EGRID file: + + { + ecl_grid_type * grid = newGRID( ); + ecl_grid_fwrite_EGRID( grid , filename ); + ecl_grid_free( grid ); + } +*/ + +void EclipseGridParser::saveEGRID( const std::string & filename) { + bool endian_flip = true;//ECL_ENDIAN_FLIP; + bool fmt_file = ecl_util_fmt_file( filename.c_str() ); + struct grdecl grdecl = get_grdecl(); + fortio_type * fortio = fortio_open_writer( filename.c_str() , fmt_file , endian_flip ); + { + float * mapaxes = NULL; + if (grdecl.mapaxes != NULL) { + mapaxes = new float[6]; + for (int i=0; i < 6; i++) + mapaxes[i]= grdecl.mapaxes[i]; + } + + ecl_grid_fwrite_EGRID_header( grdecl.dims , mapaxes , fortio ); + + if (grdecl.mapaxes != NULL) + delete[] mapaxes; + } + { + ecl_kw_type * coord_kw = newEclKW( COORD_KW , ECL_FLOAT_TYPE ); + ecl_kw_type * zcorn_kw = newEclKW( ZCORN_KW , ECL_FLOAT_TYPE ); + ecl_kw_type * actnum_kw = newEclKW( ACTNUM_KW , ECL_INT_TYPE ); + ecl_kw_type * endgrid_kw = ecl_kw_alloc( ENDGRID_KW , 0 , ECL_INT_TYPE ); + + ecl_kw_fwrite( coord_kw , fortio ); + ecl_kw_fwrite( zcorn_kw , fortio ); + ecl_kw_fwrite( actnum_kw , fortio ); + ecl_kw_fwrite( endgrid_kw , fortio ); + + ecl_kw_free( coord_kw ); + ecl_kw_free( zcorn_kw ); + ecl_kw_free( actnum_kw ); + ecl_kw_free( endgrid_kw ); + } + fortio_fclose( fortio ); +} + +/** + Will query the deck for keyword @kw; and save it to the @fortio + instance if the keyword can be found. +*/ +void EclipseGridParser::save_kw( fortio_type * fortio , const std::string & kw , ecl_type_enum ecl_type) { + ecl_kw_type * ecl_kw = newEclKW( kw , ecl_type ); + if (ecl_kw != NULL) { + ecl_kw_fwrite( ecl_kw , fortio ); + ecl_kw_free( ecl_kw ); + } +} + + +/** + Will save an ECLIPSE INIT file to @filename. Observe that the main + focus of this function is to store grid properties like PERMX and + PORO, various tabular properties like e.g. relperm tables and + thermodynamic properties are ignored. +*/ + +void EclipseGridParser::saveINIT( const std::string & filename , const ecl_grid_type * ecl_grid) { + int phases = ECL_OIL_PHASE + ECL_WATER_PHASE; + bool fmt_file = ecl_util_fmt_file( filename.c_str() ); + bool endian_flip = true;//ECL_ENDIAN_FLIP; + fortio_type * fortio = fortio_open_writer( filename.c_str() , fmt_file , endian_flip ); + { + ecl_kw_type * poro_kw = newEclKW( PORO_KW , ECL_FLOAT_TYPE ); + time_t start_date; + + { + tm td_tm = to_tm( start_date_ ); + start_date = mktime( &td_tm ); + } + + ecl_init_file_fwrite_header( fortio , ecl_grid , poro_kw , phases , start_date ); + ecl_kw_free( poro_kw ); + } + + /* This collection of keywords is somewhat arbitrary and random. */ + save_kw( fortio , "PERMX" , ECL_FLOAT_TYPE); + save_kw( fortio , "PERMY" , ECL_FLOAT_TYPE); + save_kw( fortio , "PERMZ" , ECL_FLOAT_TYPE); + + save_kw( fortio , "FIPNUM" , ECL_INT_TYPE); + save_kw( fortio , "SATNUM" , ECL_INT_TYPE); + save_kw( fortio , "EQLNUM" , ECL_INT_TYPE); + + fortio_fclose( fortio ); +} + + +/** + This is the main function used to save the state of the ECLIPSE + deck in ECLIPSE format. The function will save an INIT file and an + EGRID file. + + The input arguments are the output directory to store files in, and + the basename to use for the files; the function will build up a + ECLIPSE standard filename internally. +*/ + +void EclipseGridParser::saveEGRID_INIT( const std::string& output_dir , const std::string& basename, bool fmt_file) { + ecl_grid_type * ecl_grid = newGrid(); + char * egrid_file = ecl_util_alloc_filename( output_dir.c_str() , basename.c_str() , ECL_EGRID_FILE , fmt_file , 0); + char * init_file = ecl_util_alloc_filename( output_dir.c_str() , basename.c_str() , ECL_INIT_FILE , fmt_file , 0); + + ecl_grid_fwrite_EGRID( ecl_grid , egrid_file ); + saveINIT( init_file , ecl_grid ); + + free( init_file ); + free( egrid_file ); + ecl_grid_free( ecl_grid ); +} +#endif } // namespace Opm diff --git a/opm/core/eclipse/EclipseGridParser.hpp b/opm/core/eclipse/EclipseGridParser.hpp index 56e9ee4f..31195e77 100644 --- a/opm/core/eclipse/EclipseGridParser.hpp +++ b/opm/core/eclipse/EclipseGridParser.hpp @@ -45,6 +45,13 @@ along with OpenRS. If not, see . #include #include +#include +#ifdef HAVE_ERT +#include +#include +#endif + + namespace Opm { @@ -191,7 +198,23 @@ public: /// The units specified by the eclipse file read. const EclipseUnits& units() const; + struct grdecl get_grdecl() const; + +#ifdef HAVE_ERT + void saveEGRID_INIT( const std::string& output_dir , const std::string& basename, bool fmt_file = false); + void saveEGRID( const std::string & filename ); + void saveINIT( const std::string & filename , const ecl_grid_type * ecl_grid); + ecl_grid_type * newGrid( ); +#endif + + private: + +#ifdef HAVE_ERT + ecl_kw_type * newEclKW(const std::string &keyword , ecl_type_enum ecl_type) const; + void save_kw( fortio_type * fortio , const std::string & kw , ecl_type_enum ecl_type); +#endif + SpecialFieldPtr createSpecialField(std::istream& is, const std::string& fieldname); SpecialFieldPtr cloneSpecialField(const std::string& fieldname, const std::tr1::shared_ptr original); diff --git a/opm/core/grid/cpgpreprocess/preprocess.h b/opm/core/grid/cpgpreprocess/preprocess.h index 9592ce92..4ee9be52 100644 --- a/opm/core/grid/cpgpreprocess/preprocess.h +++ b/opm/core/grid/cpgpreprocess/preprocess.h @@ -46,6 +46,7 @@ extern "C" { const double *coord; const double *zcorn; const int *actnum; + const double *mapaxes; /* 6 Element rotation vector - can be NULL. */ }; /* Constant: I J K */ diff --git a/opm/core/utility/writeECLData.cpp b/opm/core/utility/writeECLData.cpp new file mode 100644 index 00000000..ef7eb1fd --- /dev/null +++ b/opm/core/utility/writeECLData.cpp @@ -0,0 +1,98 @@ +/* + Copyright 2012 SINTEF ICT, Applied Mathematics. + Copyright 2012 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 +#include +#include +#include + +#include +#include +#include + + +namespace Opm +{ + + static ecl_kw_type * ecl_kw_wrapper( const UnstructuredGrid& grid, + const std::string& kw_name , + const std::vector * data , + int offset , + int stride ) { + + ecl_kw_type * ecl_kw = ecl_kw_alloc( kw_name.c_str() , data->size() / stride , ECL_FLOAT_TYPE ); + if (grid.global_cell == NULL) { + for (int i=0; i < grid.number_of_cells; i++) + ecl_kw_iset_float( ecl_kw , i , (*data)[i*stride + offset]); + } else { + for (int i=0; i < grid.number_of_cells; i++) + ecl_kw_iset_float( ecl_kw , grid.global_cell[i] , (*data)[i*stride + offset]); + } + return ecl_kw; + } + + + + void writeECLData(const UnstructuredGrid& grid, + DataMap& data, + const SimulatorTimer& simtimer, + const std::string& output_dir, + const std::string& base_name) { + + int step = simtimer.currentStepNum(); + ecl_file_enum file_type = ECL_UNIFIED_RESTART_FILE; + char * filename = ecl_util_alloc_filename(output_dir.c_str() , base_name.c_str() , file_type , true , step ); + int phases = ECL_OIL_PHASE + ECL_WATER_PHASE; + double days = simtimer.currentTime() / 86400; + time_t date = 0; + int nx = grid.cartdims[0]; + int ny = grid.cartdims[1]; + int nz = grid.cartdims[2]; + int nactive = grid.number_of_cells; + ecl_rst_file_type * rst_file; + + if (step > 0 && file_type == ECL_UNIFIED_RESTART_FILE) + rst_file = ecl_rst_file_open_append( filename ); + else + rst_file = ecl_rst_file_open_write( filename ); + + ecl_rst_file_fwrite_header( rst_file , step , date , days , nx , ny , nz , nactive , phases ); + ecl_rst_file_start_solution( rst_file ); + + { + ecl_kw_type * pressure_kw = ecl_kw_wrapper( grid , "PRESSURE" , data["pressure"] , 0 , 1); + ecl_rst_file_add_kw( rst_file , pressure_kw ); + ecl_kw_free( pressure_kw ); + } + + { + ecl_kw_type * swat_kw = ecl_kw_wrapper( grid , "SWAT" , data["saturation"] , 0 , 2); + ecl_rst_file_add_kw( rst_file , swat_kw ); + ecl_kw_free( swat_kw ); + } + + ecl_rst_file_end_solution( rst_file ); + ecl_rst_file_close( rst_file ); + free(filename); + } +} + diff --git a/opm/core/utility/writeECLData.hpp b/opm/core/utility/writeECLData.hpp new file mode 100644 index 00000000..1c963c0d --- /dev/null +++ b/opm/core/utility/writeECLData.hpp @@ -0,0 +1,47 @@ +/* + Copyright 2012 SINTEF ICT, Applied Mathematics. + Copyright 2012 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 OPM_WRITEECLDATA_HEADER_INCLUDED +#define OPM_WRITEECLDATA_HEADER_INCLUDED + + +#include +#include +#include +#include +#include +#include +#include + +struct UnstructuredGrid; + +namespace Opm +{ + + // ECLIPSE output for general grids. + void writeECLData(const UnstructuredGrid& grid, + const DataMap& data, + const SimulatorTimer& simtimer, + const std::string& output_dir, + const std::string& base_name); + +} + +#endif diff --git a/tests/Makefile.am b/tests/Makefile.am index 1ec5dd26..d4b23705 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -22,7 +22,6 @@ test_column_extract \ test_lapack \ test_read_vag \ test_readpolymer \ -test_readvector \ test_sf2p \ test_writeVtkData \ unit_test From 93c813bf00c3006299224bd3d1403a35913513ce Mon Sep 17 00:00:00 2001 From: Joakim Hove Date: Thu, 28 Jun 2012 13:05:33 +0200 Subject: [PATCH 04/38] 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 05/38] 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 From 41736965ff4e09a8849c7e42d025acb1adc2e535 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Thu, 28 Jun 2012 13:27:03 +0200 Subject: [PATCH 06/38] Tentative refinement of ERT Autoconf support. Add a new macro, "ERT", that uses AC_LINK_IFELSE to test if the ECL and related libraries are available of the local computer system. Call the macro from "configure.ac". Also, adapt the main "Makefile.am" to the results of the "ERT" macro. --- Makefile.am | 34 ++++++++++++++------------ configure.ac | 54 +----------------------------------------- m4/ert.m4 | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 68 deletions(-) create mode 100644 m4/ert.m4 diff --git a/Makefile.am b/Makefile.am index 06e98c1d..f92d2c6d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -11,31 +11,35 @@ lib_LTLIBRARIES = libopmcore.la # ---------------------------------------------------------------------- # Build-time flags needed to build libopmcore.la +AM_CPPFLAGS = \ +$(ERT_CPPFLAGS) \ +$(BOOST_CPPFLAGS) + #----------------------------------------------------------------- # ERT related settings #if HAVE_ERT -ERT_LIB_PATH = $(ERT_ROOT)/lib -ERT_LIBS = -lecl -lgeometry -lutil -lpthread -lz -lgomp -ERT_LDFLAGS = -L$(ERT_LIB_PATH) $(ERT_LIBS) -ERT_INCLUDE_PATH = $(ERT_ROOT)/include -ERT_CPPFLAGS = -I$(ERT_INCLUDE_PATH) -#endif +# ERT_LIB_PATH = $(ERT_ROOT)/lib +# ERT_LIBS = -lecl -lgeometry -lutil -lpthread -lz -lgomp +# ERT_LDFLAGS = -L$(ERT_LIB_PATH) $(ERT_LIBS) +# ERT_INCLUDE_PATH = $(ERT_ROOT)/include +# ERT_CPPFLAGS = -I$(ERT_INCLUDE_PATH) -AM_CPPFLAGS = \ -$(BOOST_CPPFLAGS) \ --I$(ERT_INCLUDE_PATH) +#AM_CPPFLAGS += \ +#$(ERT_CPPFLAGS) +#endif # ---------------------------------------------------------------------- # Link-time flags needed both to successfully link the library and to # (transitively) convey inter-library dependency information. -libopmcore_la_LDFLAGS = \ -$(BOOST_LDFLAGS) \ -$(BOOST_FILESYSTEM_LIB) \ -$(BOOST_SYSTEM_LIB) \ -$(BOOST_DATE_TIME_LIB) \ +libopmcore_la_LDFLAGS = \ +$(ERT_LDFLAGS) \ +$(BOOST_LDFLAGS) \ +$(BOOST_FILESYSTEM_LIB) \ +$(BOOST_SYSTEM_LIB) \ +$(BOOST_DATE_TIME_LIB) \ $(BOOST_UNIT_TEST_FRAMEWORK_LIB) \ -$(ERT_LDFLAGS) $(LAPACK_LIBS) $(BLAS_LIBS) $(LIBS) $(FLIBS) +$(ERT_LIBS) $(LAPACK_LIBS) $(BLAS_LIBS) $(LIBS) $(FLIBS) # ---------------------------------------------------------------------- # Library constituents. SOURCES followed by HEADERS. diff --git a/configure.ac b/configure.ac index 9ed9cacd..2063f3c5 100644 --- a/configure.ac +++ b/configure.ac @@ -78,59 +78,7 @@ m4_ifdef([AM_COND_IF], UMFPACK support is disabled.])]) ]) -#----------------------------------------------------------------- -# Support for ERT configuration in the OPM build process. The -# configuration is unfortunately not really functional :-(. -# -# Define the option --with-ert=/path/to/ert/root which can be passed -# to the configure script. If we pass --with-ert=no (the default) -# support for use of ert libraries will not be added built in; -# otherwise we will build support for ERT. -# - -# The argument given to the --with-ert option will be interpreted as -# the root path of a ert installation, and the build process will -# expect to find the ert libraries in $with_ert/lib and the header -# files in $with_ert/include. There are no check for actually finding -# the required libraries and headers, and support for ert could in -# principle be configured as: -# -# configure --with-ert=yes CPPFLAGS=-I/path/to/ert/include LDFLAGS=-L/path/to/ert/lib - -AC_ARG_WITH(ert, [AS_HELP_STRING([--with-ert=], [Use ERT libraries])], [], [with_ert=no]) - -AM_CONDITIONAL([HAVE_ERT], - [test "x$ert" != "xno"]) - -# The purpose of this macro was to test if the WITH_ERT conditional -# was true, and in that case the statements: -# -# AC_SUBST([ERT_ROOT],["$with_ert"]) -# AC_DEFINE([HAVE_ERT],1,[Are the ERT libraries available]) -# -# should be invoked - but the if construction does not work, and at -# the bottom of the configuration the two statements are invoked -# unconditionally (i.e. in the end the build will be with ert -# anyway). I will award anyone who can fix this a real bear :-) - -# Joakim. -m4_ifdef([AM_COND_IF], - [AM_COND_IF([HAVE_ERT], [AC_SUBST([ERT_ROOT],["$with_ert"])], []) -]) - -AC_SUBST([ERT_ROOT],["$with_ert"]) -AC_DEFINE(HAVE_ERT,1,[Are the ERT libraries available for reading and writing ECLIPSE files.]) - -# In addition to what is present in this script ERT support is further -# configured through: -# -# o The ERT_LDFLAGS and ERT_CPPFLAGS configured in the Makefile.am -# template. -# -# o The config.h file will define the symbol HAVE_ERT if ert is built into -# the current installation. -#----------------------------------------------------------------- - - +ERT AC_CONFIG_FILES([ Makefile diff --git a/m4/ert.m4 b/m4/ert.m4 new file mode 100644 index 00000000..c7843b6a --- /dev/null +++ b/m4/ert.m4 @@ -0,0 +1,67 @@ +AC_DEFUN([_ERT_SOURCE_TEXT], +[ +AC_LANG_PROGRAM( +[[ +#include +#include +]],dnl +[[ +int sz; +sz = ecl_util_get_sizeof_ctype(ECL_INT_TYPE); +]])[]dnl +])[]dnl + +# ---------------------------------------------------------------------- + +AC_DEFUN([ERT], +[ +AC_ARG_WITH([ert], + [AS_HELP_STRING([--with-ert=], [Use ERT libraries])], + [], [with_ert=no]) + +use_ert=no + +AS_IF([test x"${with_ert}" != x"no"], +[ + _ert_LDFLAGS_SAVE="${LDFLAGS}" + _ert_LIBS_SAVE="${LIBS}" + _ert_CPPFLAGS_SAVE="${CPPFLAGS}" + _ert_CFLAGS_SAVE="${CFLAGS}" + + ERT_CPPFLAGS= + ERT_LDFLAGS= + ERT_LIBS="-lecl -lgeometry -lutil -lpthread -lz -lgomp" + AS_IF([test x"${with_ert}" != x"yes"], + [ERT_LDFLAGS="-L${with_ert}/lib" + ERT_CPPFLAGS="-I${with_ert}/include"], [:])[]dnl + + CFLAGS="-std=gnu99" + CPPFLAGS="${ERT_CPPFLAGS} ${CPPFLAGS}" + LDFLAGS="${ERT_LDFLAGS} ${LDFLAGS}" + LIBS="${ERT_LIBS} ${LIBS}" + + AC_LINK_IFELSE([_ERT_SOURCE_TEXT], + [use_ert=yes], [use_ert=no]) + + LIBS="${_ert_LIBS_SAVE}" + CPPFLAGS="${_ert_CPPFLAGS_SAVE}" + LDFLAGS="${_ert_LDFLAGS_SAVE}" + CFLAGS="${_ert_CFLAGS_SAVE}" + + AS_IF([test x"${use_ert}" == x"yes"], + [AC_SUBST([ERT_CPPFLAGS]) + AC_SUBST([ERT_LDFLAGS]) + AC_SUBST([ERT_LIBS]) + AC_DEFINE([HAVE_ERT], [1], + [Are the ERT libraries available for reading and writing ECLIPSE files.])],dnl + [:])[]dnl +], [:])[]dnl + +AM_CONDITIONAL([HAVE_ERT], [test x"${use_ert}" != x"no"]) + +# AC_MSG_ERROR( +# [**** ERT_CPPFLAGS = ${ERT_CPPFLAGS} **** +# **** ERT_LDFLAGS = ${ERT_LDFLAGS} **** +# **** ERT_LIBS = ${ERT_LIBS} **** +# ]) +]) From d2e3dbcb03920f7597aa5b5bc259ce232c9a6061 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Thu, 28 Jun 2012 14:36:45 +0200 Subject: [PATCH 07/38] Catch up to library rename: libutil -> libert_util. --- m4/ert.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/m4/ert.m4 b/m4/ert.m4 index c7843b6a..28067892 100644 --- a/m4/ert.m4 +++ b/m4/ert.m4 @@ -30,7 +30,7 @@ AS_IF([test x"${with_ert}" != x"no"], ERT_CPPFLAGS= ERT_LDFLAGS= - ERT_LIBS="-lecl -lgeometry -lutil -lpthread -lz -lgomp" + ERT_LIBS="-lecl -lgeometry -lert_util -lpthread -lz -lgomp" AS_IF([test x"${with_ert}" != x"yes"], [ERT_LDFLAGS="-L${with_ert}/lib" ERT_CPPFLAGS="-I${with_ert}/include"], [:])[]dnl From 89e099b72430aec08e0f637125f12f45cf32107a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Thu, 28 Jun 2012 14:39:30 +0200 Subject: [PATCH 08/38] Remove obsolete comments. --- Makefile.am | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/Makefile.am b/Makefile.am index f92d2c6d..e23fdb53 100644 --- a/Makefile.am +++ b/Makefile.am @@ -15,19 +15,6 @@ AM_CPPFLAGS = \ $(ERT_CPPFLAGS) \ $(BOOST_CPPFLAGS) -#----------------------------------------------------------------- -# ERT related settings -#if HAVE_ERT -# ERT_LIB_PATH = $(ERT_ROOT)/lib -# ERT_LIBS = -lecl -lgeometry -lutil -lpthread -lz -lgomp -# ERT_LDFLAGS = -L$(ERT_LIB_PATH) $(ERT_LIBS) -# ERT_INCLUDE_PATH = $(ERT_ROOT)/include -# ERT_CPPFLAGS = -I$(ERT_INCLUDE_PATH) - -#AM_CPPFLAGS += \ -#$(ERT_CPPFLAGS) -#endif - # ---------------------------------------------------------------------- # Link-time flags needed both to successfully link the library and to # (transitively) convey inter-library dependency information. From ebf4b63aa49ebddb9d1fb119028058b8f8c56dd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Thu, 28 Jun 2012 14:42:04 +0200 Subject: [PATCH 09/38] Use a "const" DataMap object. As a fall-out, we can no longer use std::map::operator[], because that function cannot be applied to "const" objects. Replace by .find(). --- opm/core/utility/writeECLData.cpp | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/opm/core/utility/writeECLData.cpp b/opm/core/utility/writeECLData.cpp index ef7eb1fd..9c34f0eb 100644 --- a/opm/core/utility/writeECLData.cpp +++ b/opm/core/utility/writeECLData.cpp @@ -53,7 +53,7 @@ namespace Opm void writeECLData(const UnstructuredGrid& grid, - DataMap& data, + const DataMap& data, const SimulatorTimer& simtimer, const std::string& output_dir, const std::string& base_name) { @@ -79,15 +79,21 @@ namespace Opm ecl_rst_file_start_solution( rst_file ); { - ecl_kw_type * pressure_kw = ecl_kw_wrapper( grid , "PRESSURE" , data["pressure"] , 0 , 1); - ecl_rst_file_add_kw( rst_file , pressure_kw ); - ecl_kw_free( pressure_kw ); + DataMap::const_iterator i = data.find("pressure"); + if (i != data.end()) { + ecl_kw_type * pressure_kw = ecl_kw_wrapper( grid , "PRESSURE" , i->second , 0 , 1); + ecl_rst_file_add_kw( rst_file , pressure_kw ); + ecl_kw_free( pressure_kw ); + } } { - ecl_kw_type * swat_kw = ecl_kw_wrapper( grid , "SWAT" , data["saturation"] , 0 , 2); - ecl_rst_file_add_kw( rst_file , swat_kw ); - ecl_kw_free( swat_kw ); + DataMap::const_iterator i = data.find("saturation"); + if (i != data.end()) { + ecl_kw_type * swat_kw = ecl_kw_wrapper( grid , "SWAT" , i->second , 0 , 2); + ecl_rst_file_add_kw( rst_file , swat_kw ); + ecl_kw_free( swat_kw ); + } } ecl_rst_file_end_solution( rst_file ); From 6f26b3b46e4d54bf5111f35db78968484c61bfc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Thu, 28 Jun 2012 14:44:37 +0200 Subject: [PATCH 10/38] Update ERT references to those output by m4/ert.m4 macro. --- tests/Makefile.am | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/tests/Makefile.am b/tests/Makefile.am index d4b23705..66faa1a5 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,11 +1,9 @@ -ERT_INCLUDE_PATH = $(ERT_ROOT)/include +AM_CPPFLAGS = \ +-I$(top_srcdir) \ +$(BOOST_CPPFLAGS) \ +$(ERT_CPPFLAGS) -AM_CPPFLAGS = \ --I$(top_srcdir) \ -$(BOOST_CPPFLAGS) \ --I$(ERT_INCLUDE_PATH) - -LDFLAGS = $(BOOST_LDFLAGS) +LDFLAGS = $(BOOST_LDFLAGS) $(ERT_LDFLAGS) LDADD = $(top_builddir)/libopmcore.la From 0e1dcb2c0d6c134cd6670948aa6747e3fa885881 Mon Sep 17 00:00:00 2001 From: Joakim Hove Date: Thu, 28 Jun 2012 16:17:51 +0200 Subject: [PATCH 11/38] Using Opm::unit::convert for seconds -> days conversion. --- opm/core/utility/writeECLData.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/opm/core/utility/writeECLData.cpp b/opm/core/utility/writeECLData.cpp index 9c34f0eb..5e9d4205 100644 --- a/opm/core/utility/writeECLData.cpp +++ b/opm/core/utility/writeECLData.cpp @@ -23,6 +23,8 @@ #include #include #include +#include + #include #include @@ -30,6 +32,7 @@ #include + namespace Opm { @@ -60,9 +63,10 @@ namespace Opm int step = simtimer.currentStepNum(); ecl_file_enum file_type = ECL_UNIFIED_RESTART_FILE; - char * filename = ecl_util_alloc_filename(output_dir.c_str() , base_name.c_str() , file_type , true , step ); + bool fmt_file = true; + char * filename = ecl_util_alloc_filename(output_dir.c_str() , base_name.c_str() , file_type , fmt_file , step ); int phases = ECL_OIL_PHASE + ECL_WATER_PHASE; - double days = simtimer.currentTime() / 86400; + double days = Opm::unit::convert::to(simtimer.currentTime(), Opm::unit::day); time_t date = 0; int nx = grid.cartdims[0]; int ny = grid.cartdims[1]; From dd6e0fd3832912cc546e72a04b462a17a91068cb Mon Sep 17 00:00:00 2001 From: Joakim Hove Date: Thu, 28 Jun 2012 16:18:54 +0200 Subject: [PATCH 12/38] Removed $(FLIBS) from linking. --- Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index e23fdb53..115cd789 100644 --- a/Makefile.am +++ b/Makefile.am @@ -26,7 +26,7 @@ $(BOOST_FILESYSTEM_LIB) \ $(BOOST_SYSTEM_LIB) \ $(BOOST_DATE_TIME_LIB) \ $(BOOST_UNIT_TEST_FRAMEWORK_LIB) \ -$(ERT_LIBS) $(LAPACK_LIBS) $(BLAS_LIBS) $(LIBS) $(FLIBS) +$(ERT_LIBS) $(LAPACK_LIBS) $(BLAS_LIBS) $(LIBS) # ---------------------------------------------------------------------- # Library constituents. SOURCES followed by HEADERS. From c437eba207e4a434b0e807155d0137295ce52ab4 Mon Sep 17 00:00:00 2001 From: Joakim Hove Date: Thu, 28 Jun 2012 16:19:04 +0200 Subject: [PATCH 13/38] Removed $(FLIBS) from linking. --- tests/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Makefile.am b/tests/Makefile.am index 66faa1a5..29003343 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -3,7 +3,7 @@ AM_CPPFLAGS = \ $(BOOST_CPPFLAGS) \ $(ERT_CPPFLAGS) -LDFLAGS = $(BOOST_LDFLAGS) $(ERT_LDFLAGS) +AM_LDFLAGS = $(BOOST_LDFLAGS) $(ERT_LDFLAGS) LDADD = $(top_builddir)/libopmcore.la @@ -44,7 +44,7 @@ test_column_extract_SOURCES = test_column_extract.cpp test_column_extract_LDADD = $(LDADD) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) test_lapack_SOURCES = test_lapack.cpp -test_lapack_LDADD = $(LAPACK_LIBS) $(BLAS_LIBS) $(LIBS) $(FLIBS) +test_lapack_LDADD = $(LAPACK_LIBS) $(BLAS_LIBS) $(LIBS) test_readpolymer_SOURCES = test_readpolymer.cpp test_read_vag_SOURCES = test_read_vag.cpp From 9e885dc7053bf1598f20189c50f7685eb8dd7e98 Mon Sep 17 00:00:00 2001 From: Joakim Hove Date: Thu, 28 Jun 2012 16:19:16 +0200 Subject: [PATCH 14/38] Removed $(FLIBS) from linking. --- examples/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/Makefile.am b/examples/Makefile.am index b2887f93..5fafc37d 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -45,5 +45,5 @@ noinst_PROGRAMS += spu_2p spu_2p_SOURCES = spu_2p.cpp spu_2p_LDADD = \ $(LDADD) \ -$(LAPACK_LIBS) $(BLAS_LIBS) $(LIBS) $(FLIBS) +$(LAPACK_LIBS) $(BLAS_LIBS) $(LIBS) endif From 2b610dfce759f45f560d0ec7556aa6930a81ace6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Wed, 22 Aug 2012 11:40:13 +0200 Subject: [PATCH 15/38] Assert that all cells are in range. This will (hopefully) prevent the issues fixed in commits aaae8e1 and 462c7cf from reoccurring. --- opm/core/grid/cpgpreprocess/preprocess.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/opm/core/grid/cpgpreprocess/preprocess.c b/opm/core/grid/cpgpreprocess/preprocess.c index 84e9e8fe..dc274160 100644 --- a/opm/core/grid/cpgpreprocess/preprocess.c +++ b/opm/core/grid/cpgpreprocess/preprocess.c @@ -590,6 +590,9 @@ get_zcorn_sign(int nx, int ny, int nz, const int *actnum, c1 = i/2 + nx*(j/2 + ny*(k/2)); c2 = i/2 + nx*(j/2 + ny*((k+1)/2)); + assert (c1 < (nx * ny * nz)); + assert (c2 < (nx * ny * nz)); + if (((actnum == NULL) || (actnum[c1] && actnum[c2])) && (z2 < z1)) { From 3f5ffcd75a3c011e381337fd0ef249e5202c9f57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halvor=20M=C3=B8ll=20Nilsen?= Date: Tue, 21 Aug 2012 15:23:46 +0200 Subject: [PATCH 16/38] added writing of reorder iterations for each cell --- .../simulator/SimulatorIncompTwophase.cpp | 134 +++++++++++++----- .../reorder/TransportModelTwophase.cpp | 11 +- .../reorder/TransportModelTwophase.hpp | 10 +- 3 files changed, 108 insertions(+), 47 deletions(-) diff --git a/opm/core/simulator/SimulatorIncompTwophase.cpp b/opm/core/simulator/SimulatorIncompTwophase.cpp index 2d06014e..35b3e84b 100644 --- a/opm/core/simulator/SimulatorIncompTwophase.cpp +++ b/opm/core/simulator/SimulatorIncompTwophase.cpp @@ -77,7 +77,6 @@ namespace Opm private: // Data. - // Parameters for output. bool output_; bool output_vtk_; @@ -133,8 +132,38 @@ namespace Opm return pimpl_->run(timer, state, well_state); } - - + static void reportVolumes(std::ostream &os,double satvol[2],double tot_porevol_init, + double tot_injected[2],double tot_produced[2], + double injected[2], double produced[2], + double init_satvol[2]){ + std::cout.precision(5); + const int width = 18; + os << "\nVolume balance report (all numbers relative to total pore volume).\n"; + os << " Saturated volumes: " + << std::setw(width) << satvol[0]/tot_porevol_init + << std::setw(width) << satvol[1]/tot_porevol_init << std::endl; + os << " Injected volumes: " + << std::setw(width) << injected[0]/tot_porevol_init + << std::setw(width) << injected[1]/tot_porevol_init << std::endl; + os << " Produced volumes: " + << std::setw(width) << produced[0]/tot_porevol_init + << std::setw(width) << produced[1]/tot_porevol_init << std::endl; + os << " Total inj volumes: " + << std::setw(width) << tot_injected[0]/tot_porevol_init + << std::setw(width) << tot_injected[1]/tot_porevol_init << std::endl; + os << " Total prod volumes: " + << std::setw(width) << tot_produced[0]/tot_porevol_init + << std::setw(width) << tot_produced[1]/tot_porevol_init << std::endl; + os << " In-place + prod - inj: " + << std::setw(width) << (satvol[0] + tot_produced[0] - tot_injected[0])/tot_porevol_init + << std::setw(width) << (satvol[1] + tot_produced[1] - tot_injected[1])/tot_porevol_init << std::endl; + os << " Init - now - pr + inj: " + << std::setw(width) << (init_satvol[0] - satvol[0] - tot_produced[0] + tot_injected[0])/tot_porevol_init + << std::setw(width) << (init_satvol[1] - satvol[1] - tot_produced[1] + tot_injected[1])/tot_porevol_init + << std::endl; + os.precision(8); + } + static void outputStateVtk(const UnstructuredGrid& grid, const Opm::TwophaseState& state, const int step, @@ -163,6 +192,49 @@ namespace Opm dm["velocity"] = &cell_velocity; Opm::writeVtkData(grid, dm, vtkfile); } + static void outputVectorMatlab(const std::string name, + const std::vector vec, + const int step, + const std::string& output_dir) + { + std::ostringstream fname; + fname << output_dir << "/" << name; + boost::filesystem::path fpath = fname.str(); + try { + create_directories(fpath); + } + catch (...) { + THROW("Creating directories failed: " << fpath); + } + fname << "/" << std::setw(3) << std::setfill('0') << step << ".txt"; + std::ofstream file(fname.str().c_str()); + if (!file) { + THROW("Failed to open " << fname.str()); + } + std::copy(vec.begin(), vec.end(), std::ostream_iterator(file, "\n")); + } + + static void outputVectorMatlab(const std::string name, + const std::vector vec, + const int step, + const std::string& output_dir) + { + std::ostringstream fname; + fname << output_dir << "/" << name; + boost::filesystem::path fpath = fname.str(); + try { + create_directories(fpath); + } + catch (...) { + THROW("Creating directories failed: " << fpath); + } + fname << "/" << std::setw(3) << std::setfill('0') << step << ".txt"; + std::ofstream file(fname.str().c_str()); + if (!file) { + THROW("Failed to open " << fname.str()); + } + std::copy(vec.begin(), vec.end(), std::ostream_iterator(file, "\n")); + } static void outputStateMatlab(const UnstructuredGrid& grid, @@ -377,6 +449,9 @@ namespace Opm outputStateVtk(grid_, state, timer.currentStepNum(), output_dir_); } outputStateMatlab(grid_, state, timer.currentStepNum(), output_dir_); + outputVectorMatlab(std::string("reorder_it"), + tsolver_.getReorderIterations(), + timer.currentStepNum(), output_dir_); } SimulatorReport sreport; @@ -471,8 +546,16 @@ namespace Opm stepsize, state.saturation()); Opm::computeInjectedProduced(props_, state.saturation(), transport_src, stepsize, injected, produced); if (use_segregation_split_) { - tsolver_.solveGravity(columns_, &porevol[0], stepsize, state.saturation()); + tsolver_.solveGravity(columns_, &porevol[0], stepsize, state.saturation()); } + watercut.push(timer.currentTime() + timer.currentStepLength(), + produced[0]/(produced[0] + produced[1]), + tot_produced[0]/tot_porevol_init); + if (wells_) { + wellreport.push(props_, *wells_, state.saturation(), + timer.currentTime() + timer.currentStepLength(), + well_state.bhp(), well_state.perfRates()); + } } transport_timer.stop(); double tt = transport_timer.secsSinceStart(); @@ -485,41 +568,11 @@ namespace Opm tot_injected[1] += injected[1]; tot_produced[0] += produced[0]; tot_produced[1] += produced[1]; - std::cout.precision(5); - const int width = 18; - std::cout << "\nVolume balance report (all numbers relative to total pore volume).\n"; - std::cout << " Saturated volumes: " - << std::setw(width) << satvol[0]/tot_porevol_init - << std::setw(width) << satvol[1]/tot_porevol_init << std::endl; - std::cout << " Injected volumes: " - << std::setw(width) << injected[0]/tot_porevol_init - << std::setw(width) << injected[1]/tot_porevol_init << std::endl; - std::cout << " Produced volumes: " - << std::setw(width) << produced[0]/tot_porevol_init - << std::setw(width) << produced[1]/tot_porevol_init << std::endl; - std::cout << " Total inj volumes: " - << std::setw(width) << tot_injected[0]/tot_porevol_init - << std::setw(width) << tot_injected[1]/tot_porevol_init << std::endl; - std::cout << " Total prod volumes: " - << std::setw(width) << tot_produced[0]/tot_porevol_init - << std::setw(width) << tot_produced[1]/tot_porevol_init << std::endl; - std::cout << " In-place + prod - inj: " - << std::setw(width) << (satvol[0] + tot_produced[0] - tot_injected[0])/tot_porevol_init - << std::setw(width) << (satvol[1] + tot_produced[1] - tot_injected[1])/tot_porevol_init << std::endl; - std::cout << " Init - now - pr + inj: " - << std::setw(width) << (init_satvol[0] - satvol[0] - tot_produced[0] + tot_injected[0])/tot_porevol_init - << std::setw(width) << (init_satvol[1] - satvol[1] - tot_produced[1] + tot_injected[1])/tot_porevol_init - << std::endl; - std::cout.precision(8); - - watercut.push(timer.currentTime() + timer.currentStepLength(), - produced[0]/(produced[0] + produced[1]), - tot_produced[0]/tot_porevol_init); - if (wells_) { - wellreport.push(props_, *wells_, state.saturation(), - timer.currentTime() + timer.currentStepLength(), - well_state.bhp(), well_state.perfRates()); - } + //reportVolumes(std::cout,satvol[0],&tot_porevol_init[0],&tot_injected[0]); + Opm::reportVolumes(std::cout,satvol, tot_porevol_init, + tot_injected, tot_produced, + injected, produced, + init_satvol); sreport.total_time = step_timer.secsSinceStart(); if (output_) { sreport.reportParam(tstep_os); @@ -531,6 +584,9 @@ namespace Opm outputStateVtk(grid_, state, timer.currentStepNum(), output_dir_); } outputStateMatlab(grid_, state, timer.currentStepNum(), output_dir_); + outputVectorMatlab(std::string("reorder_it"), + tsolver_.getReorderIterations(), + timer.currentStepNum(), output_dir_); outputWaterCut(watercut, output_dir_); if (wells_) { outputWellReport(wellreport, output_dir_); diff --git a/opm/core/transport/reorder/TransportModelTwophase.cpp b/opm/core/transport/reorder/TransportModelTwophase.cpp index b3630ea7..49cafa49 100644 --- a/opm/core/transport/reorder/TransportModelTwophase.cpp +++ b/opm/core/transport/reorder/TransportModelTwophase.cpp @@ -52,6 +52,7 @@ namespace Opm source_(0), dt_(0.0), saturation_(grid.number_of_cells, -1.0), + reorder_iterations_(grid.number_of_cells, 0), fractionalflow_(grid.number_of_cells, -1.0), mob_(2*grid.number_of_cells, -1.0) #ifdef EXPERIMENT_GAUSS_SEIDEL @@ -101,7 +102,7 @@ namespace Opm &seq[0], &comp[0], &ncomp, &ia_downw_[0], &ja_downw_[0]); #endif - + std::fill(reorder_iterations_.begin(),reorder_iterations_.end(),0); reorderAndTransport(grid_, darcyflux); toBothSat(saturation_, saturation); } @@ -170,9 +171,11 @@ namespace Opm // if (std::fabs(r0) < tol_) { // return; // } - int iters_used; + int iters_used=0; // saturation_[cell] = modifiedRegulaFalsi(res, smin_[2*cell], smax_[2*cell], maxit_, tol_, iters_used); saturation_[cell] = RootFinder::solve(res, saturation_[cell], 0.0, 1.0, maxit_, tol_, iters_used); + // add if it is iteration on an out loop + reorder_iterations_[cell] = reorder_iterations_[cell] + iters_used; fractionalflow_[cell] = fracFlow(saturation_[cell], cell); } @@ -544,8 +547,9 @@ namespace Opm const int cell = cells[pos]; GravityResidual res(*this, cells, pos, gravflux); if (std::fabs(res(saturation_[cell])) > tol_) { - int iters_used; + int iters_used=0; saturation_[cell] = RootFinder::solve(res, smin_[2*cell], smax_[2*cell], maxit_, tol_, iters_used); + reorder_iterations_[cell] = reorder_iterations_[cell] + iters_used; } saturation_[cell] = std::min(std::max(saturation_[cell], smin_[2*cell]), smax_[2*cell]); mobility(saturation_[cell], cell, &mob_[2*cell]); @@ -641,7 +645,6 @@ namespace Opm toBothSat(saturation_, saturation); } - } // namespace Opm diff --git a/opm/core/transport/reorder/TransportModelTwophase.hpp b/opm/core/transport/reorder/TransportModelTwophase.hpp index 74ed2bfe..69297607 100644 --- a/opm/core/transport/reorder/TransportModelTwophase.hpp +++ b/opm/core/transport/reorder/TransportModelTwophase.hpp @@ -23,7 +23,7 @@ #include #include #include - +#include struct UnstructuredGrid; namespace Opm @@ -74,7 +74,8 @@ namespace Opm const double* porevolume, const double dt, std::vector& saturation); - + void reportIterations(std::ostream &os); + const std::vector& getReorderIterations(){return reorder_iterations_;}; private: virtual void solveSingleCell(const int cell); virtual void solveMultiCell(const int num_cells, const int* cells); @@ -83,8 +84,7 @@ namespace Opm const int pos, const double* gravflux); int solveGravityColumn(const std::vector& cells); - - private: + private: const UnstructuredGrid& grid_; const IncompPropertiesInterface& props_; const double* visc_; @@ -99,6 +99,8 @@ namespace Opm double dt_; std::vector saturation_; // one per cell, only water saturation! std::vector fractionalflow_; // = m[0]/(m[0] + m[1]) per cell + std::vector reorder_iterations_; + //std::vector reorder_fval_; // For gravity segregation. std::vector gravflux_; std::vector mob_; From 36fb50e8032eab68323f6979a4aa62b70978b6a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halvor=20M=C3=B8ll=20Nilsen?= Date: Fri, 24 Aug 2012 12:52:41 +0200 Subject: [PATCH 17/38] Corrected typing pointed out by atgeirr in respose to pullrequest --- .../simulator/SimulatorIncompTwophase.cpp | 101 +++++++++--------- .../reorder/TransportModelTwophase.cpp | 8 +- .../reorder/TransportModelTwophase.hpp | 4 +- 3 files changed, 60 insertions(+), 53 deletions(-) diff --git a/opm/core/simulator/SimulatorIncompTwophase.cpp b/opm/core/simulator/SimulatorIncompTwophase.cpp index 35b3e84b..d4e7459f 100644 --- a/opm/core/simulator/SimulatorIncompTwophase.cpp +++ b/opm/core/simulator/SimulatorIncompTwophase.cpp @@ -132,10 +132,11 @@ namespace Opm return pimpl_->run(timer, state, well_state); } - static void reportVolumes(std::ostream &os,double satvol[2],double tot_porevol_init, - double tot_injected[2],double tot_produced[2], - double injected[2], double produced[2], - double init_satvol[2]){ + static void reportVolumes(std::ostream &os,double satvol[2],double tot_porevol_init, + double tot_injected[2], double tot_produced[2], + double injected[2], double produced[2], + double init_satvol[2]) + { std::cout.precision(5); const int width = 18; os << "\nVolume balance report (all numbers relative to total pore volume).\n"; @@ -163,7 +164,7 @@ namespace Opm << std::endl; os.precision(8); } - + static void outputStateVtk(const UnstructuredGrid& grid, const Opm::TwophaseState& state, const int step, @@ -174,10 +175,10 @@ namespace Opm vtkfilename << output_dir << "/vtk_files"; boost::filesystem::path fpath(vtkfilename.str()); try { - create_directories(fpath); + create_directories(fpath); } catch (...) { - THROW("Creating directories failed: " << fpath); + THROW("Creating directories failed: " << fpath); } vtkfilename << "/" << std::setw(3) << std::setfill('0') << step << ".vtu"; std::ofstream vtkfile(vtkfilename.str().c_str()); @@ -193,47 +194,47 @@ namespace Opm Opm::writeVtkData(grid, dm, vtkfile); } static void outputVectorMatlab(const std::string name, - const std::vector vec, - const int step, - const std::string& output_dir) + const std::vector& vec, + const int step, + const std::string& output_dir) { - std::ostringstream fname; - fname << output_dir << "/" << name; - boost::filesystem::path fpath = fname.str(); - try { - create_directories(fpath); - } - catch (...) { - THROW("Creating directories failed: " << fpath); - } - fname << "/" << std::setw(3) << std::setfill('0') << step << ".txt"; - std::ofstream file(fname.str().c_str()); - if (!file) { - THROW("Failed to open " << fname.str()); - } - std::copy(vec.begin(), vec.end(), std::ostream_iterator(file, "\n")); + std::ostringstream fname; + fname << output_dir << "/" << name; + boost::filesystem::path fpath = fname.str(); + try { + create_directories(fpath); + } + catch (...) { + THROW("Creating directories failed: " << fpath); + } + fname << "/" << std::setw(3) << std::setfill('0') << step << ".txt"; + std::ofstream file(fname.str().c_str()); + if (!file) { + THROW("Failed to open " << fname.str()); + } + std::copy(vec.begin(), vec.end(), std::ostream_iterator(file, "\n")); } static void outputVectorMatlab(const std::string name, - const std::vector vec, - const int step, - const std::string& output_dir) + const std::vector vec, + const int step, + const std::string& output_dir) { - std::ostringstream fname; - fname << output_dir << "/" << name; - boost::filesystem::path fpath = fname.str(); - try { - create_directories(fpath); - } - catch (...) { - THROW("Creating directories failed: " << fpath); - } - fname << "/" << std::setw(3) << std::setfill('0') << step << ".txt"; - std::ofstream file(fname.str().c_str()); - if (!file) { - THROW("Failed to open " << fname.str()); - } - std::copy(vec.begin(), vec.end(), std::ostream_iterator(file, "\n")); + std::ostringstream fname; + fname << output_dir << "/" << name; + boost::filesystem::path fpath = fname.str(); + try { + create_directories(fpath); + } + catch (...) { + THROW("Creating directories failed: " << fpath); + } + fname << "/" << std::setw(3) << std::setfill('0') << step << ".txt"; + std::ofstream file(fname.str().c_str()); + if (!file) { + THROW("Failed to open " << fname.str()); + } + std::copy(vec.begin(), vec.end(), std::ostream_iterator(file, "\n")); } @@ -255,10 +256,10 @@ namespace Opm fname << output_dir << "/" << it->first; boost::filesystem::path fpath = fname.str(); try { - create_directories(fpath); + create_directories(fpath); } catch (...) { - THROW("Creating directories failed: " << fpath); + THROW("Creating directories failed: " << fpath); } fname << "/" << std::setw(3) << std::setfill('0') << step << ".txt"; std::ofstream file(fname.str().c_str()); @@ -543,18 +544,18 @@ namespace Opm } for (int tr_substep = 0; tr_substep < num_transport_substeps_; ++tr_substep) { tsolver_.solve(&state.faceflux()[0], &porevol[0], &transport_src[0], - stepsize, state.saturation()); + stepsize, state.saturation()); Opm::computeInjectedProduced(props_, state.saturation(), transport_src, stepsize, injected, produced); if (use_segregation_split_) { - tsolver_.solveGravity(columns_, &porevol[0], stepsize, state.saturation()); + tsolver_.solveGravity(columns_, &porevol[0], stepsize, state.saturation()); } watercut.push(timer.currentTime() + timer.currentStepLength(), produced[0]/(produced[0] + produced[1]), tot_produced[0]/tot_porevol_init); if (wells_) { - wellreport.push(props_, *wells_, state.saturation(), - timer.currentTime() + timer.currentStepLength(), - well_state.bhp(), well_state.perfRates()); + wellreport.push(props_, *wells_, state.saturation(), + timer.currentTime() + timer.currentStepLength(), + well_state.bhp(), well_state.perfRates()); } } transport_timer.stop(); diff --git a/opm/core/transport/reorder/TransportModelTwophase.cpp b/opm/core/transport/reorder/TransportModelTwophase.cpp index 49cafa49..b6451809 100644 --- a/opm/core/transport/reorder/TransportModelTwophase.cpp +++ b/opm/core/transport/reorder/TransportModelTwophase.cpp @@ -171,7 +171,7 @@ namespace Opm // if (std::fabs(r0) < tol_) { // return; // } - int iters_used=0; + int iters_used = 0; // saturation_[cell] = modifiedRegulaFalsi(res, smin_[2*cell], smax_[2*cell], maxit_, tol_, iters_used); saturation_[cell] = RootFinder::solve(res, saturation_[cell], 0.0, 1.0, maxit_, tol_, iters_used); // add if it is iteration on an out loop @@ -547,7 +547,7 @@ namespace Opm const int cell = cells[pos]; GravityResidual res(*this, cells, pos, gravflux); if (std::fabs(res(saturation_[cell])) > tol_) { - int iters_used=0; + int iters_used = 0; saturation_[cell] = RootFinder::solve(res, smin_[2*cell], smax_[2*cell], maxit_, tol_, iters_used); reorder_iterations_[cell] = reorder_iterations_[cell] + iters_used; } @@ -645,6 +645,10 @@ namespace Opm toBothSat(saturation_, saturation); } + void TransportModelTwophase::getReorderIterations() + { + return reorder_iterations_; + }; } // namespace Opm diff --git a/opm/core/transport/reorder/TransportModelTwophase.hpp b/opm/core/transport/reorder/TransportModelTwophase.hpp index 69297607..358baaa3 100644 --- a/opm/core/transport/reorder/TransportModelTwophase.hpp +++ b/opm/core/transport/reorder/TransportModelTwophase.hpp @@ -74,7 +74,9 @@ namespace Opm const double* porevolume, const double dt, std::vector& saturation); - void reportIterations(std::ostream &os); + //// Return reorder iterations + //// + //// \param[out] vector of iteration per cell const std::vector& getReorderIterations(){return reorder_iterations_;}; private: virtual void solveSingleCell(const int cell); From cf111e1b0423967156f535b13adcbccee52ef3d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Fri, 24 Aug 2012 16:31:15 +0200 Subject: [PATCH 18/38] Honour exact interface of LAPACK routine DGTSV. The "MAT_SIZE_T" is not necessarily equivalent to 'int'. --- opm/core/transport/GravityColumnSolver_impl.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/opm/core/transport/GravityColumnSolver_impl.hpp b/opm/core/transport/GravityColumnSolver_impl.hpp index 5d5c6445..7e31778c 100644 --- a/opm/core/transport/GravityColumnSolver_impl.hpp +++ b/opm/core/transport/GravityColumnSolver_impl.hpp @@ -175,10 +175,10 @@ namespace Opm } // model_.sourceTerms(); // Not needed // Solve. - const int num_rhs = 1; - int info = 0; + const MAT_SIZE_T num_rhs = 1, colSize = col_size; + MAT_SIZE_T info = 0; // Solution will be written to rhs. - dgtsv_(&col_size, &num_rhs, DL, D, DU, &rhs[0], &col_size, &info); + dgtsv_(&colSize, &num_rhs, DL, D, DU, &rhs[0], &colSize, &info); if (info != 0) { THROW("Lapack reported error in dgtsv: " << info); } From 47a0b56b963e9b78d1db2fe556613ce7c918e5be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Fri, 24 Aug 2012 16:35:34 +0200 Subject: [PATCH 19/38] Unequivocally exclude MATLAB timing printing. It is not actually needed and prevents building when symbol MATLAB_MEX_FILE is defined. --- opm/core/transport/reorder/TransportModelInterface.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/opm/core/transport/reorder/TransportModelInterface.cpp b/opm/core/transport/reorder/TransportModelInterface.cpp index c52b528d..f8e138a3 100644 --- a/opm/core/transport/reorder/TransportModelInterface.cpp +++ b/opm/core/transport/reorder/TransportModelInterface.cpp @@ -35,6 +35,7 @@ void Opm::TransportModelInterface::reorderAndTransport(const UnstructuredGrid& g // Invoke appropriate solve method for each interdependent component. for (int comp = 0; comp < ncomponents; ++comp) { +#if 0 #ifdef MATLAB_MEX_FILE // \TODO replace this with general signal handling code, check if it costs performance. if (interrupt_signal) { @@ -42,6 +43,7 @@ void Opm::TransportModelInterface::reorderAndTransport(const UnstructuredGrid& g "cells finished.\n", i, grid.number_of_cells); break; } +#endif #endif const int comp_size = components[comp + 1] - components[comp]; if (comp_size == 1) { From 47f9fbd17d07861704fffd1e01860abda1edc1fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Fri, 24 Aug 2012 16:49:50 +0200 Subject: [PATCH 20/38] Honour exact interfaces of LAPACK routines. The size type, MAT_SIZE_T, is not necessarily equivalent to 'int'. --- tests/test_lapack.cpp | 54 ++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/tests/test_lapack.cpp b/tests/test_lapack.cpp index 3f5aff91..56b0bbb9 100644 --- a/tests/test_lapack.cpp +++ b/tests/test_lapack.cpp @@ -24,34 +24,36 @@ namespace { struct BandMatrixCoeff { - BandMatrixCoeff(int N, int ku, int kl) : ku_(ku), kl_(kl), nrow_(2*kl + ku + 1), N_(N) { + BandMatrixCoeff(MAT_SIZE_T N, MAT_SIZE_T ku, MAT_SIZE_T kl) + : ku_(ku), kl_(kl), nrow_(2 * kl + ku + 1), N_(N) + { } // compute the position where to store the coefficient of a matrix A_{i,j} (i,j=0,...,N-1) // in a array which is sent to the band matrix solver of LAPACK. - int operator ()(int i, int j) { + int operator ()(MAT_SIZE_T i, MAT_SIZE_T j) { return kl_ + ku_ + i - j + j*nrow_; } - const int ku_; - const int kl_; - const int nrow_; - const int N_; + const MAT_SIZE_T ku_; + const MAT_SIZE_T kl_; + const MAT_SIZE_T nrow_; + const MAT_SIZE_T N_; }; } //end anonymous namespace int main() { - const int N = 5; - const int nrhs = 1; + const MAT_SIZE_T N = 5; + const MAT_SIZE_T nrhs = 1; double DU[N-1] = { 2.1, -1.0, 1.9, 8.0 }; double D[N] = { 3.0, 2.3, -5.0, -0.9, 7.1 }; double DL[N-1] = { 3.4, 3.6, 7.0, -6.0 }; double B[N] = { 2.7, -0.5, 2.6, 0.6, 2.7 }; // double B[N] = { 2.7, -0.5, 2.6, 0.6, 2.7 }; - int info = 0; + MAT_SIZE_T info = 0; dgtsv_(&N, &nrhs, DL, D, DU, B, &N, &info); if (info == 0) { for (int i = 0; i < N; ++i) { @@ -64,12 +66,12 @@ int main() std::cout << std::endl; //test of dgbsv_ - int ldb = N; - int lda = N; - std::vector ipiv(N, 0); + MAT_SIZE_T ldb = N; + MAT_SIZE_T lda = N; + std::vector ipiv(N, 0); std::vector AA(N*N, 0.); std::vector BB(N, 0.); - for (int i = 0; i < N; ++i) { + for (MAT_SIZE_T i = 0; i < N; ++i) { AA[i + i*N] = 10.; if (i > 0) { AA[i + (i - 1)*N] = i; @@ -78,31 +80,31 @@ int main() BB[i] = i; } - for (int i = 0; i < N; ++i) { - for (int j = 0; j < N; ++j) { + for (MAT_SIZE_T i = 0; i < N; ++i) { + for (MAT_SIZE_T j = 0; j < N; ++j) { std::cout << " " << AA[i + j*N]; } std::cout << " " << std::endl; } std::cout << std::endl; - int kl = 1; - int ku = 1; - int nrowAB = 2*kl + ku + 1; - int ldab = nrowAB; + MAT_SIZE_T kl = 1; + MAT_SIZE_T ku = 1; + MAT_SIZE_T nrowAB = 2*kl + ku + 1; + MAT_SIZE_T ldab = nrowAB; std::vector AB(nrowAB*N, 0.); BandMatrixCoeff bmc(N, ku, kl); // Rewrite AA matrix in band format AB - for (int i = 0; i < N; ++i) { - for (int j = -1; j < 2; ++j) { + for (MAT_SIZE_T i = 0; i < N; ++i) { + for (MAT_SIZE_T j = -1; j < 2; ++j) { if (i + j > -1 && i + j < N) AB[bmc(i, i + j)] = AA[i + N*(i + j)]; } } - for (int i = 0; i < nrowAB; ++i) { - for (int j = 0; j < N; ++j) { + for (MAT_SIZE_T i = 0; i < nrowAB; ++i) { + for (MAT_SIZE_T j = 0; j < N; ++j) { std::cout << " " << AB[i + j*nrowAB]; } std::cout << " " << std::endl; @@ -113,7 +115,7 @@ int main() dgesv_(&N ,&nrhs, &AA[0], &lda, &ipiv[0], &BB[0], &ldb, &info); if (info == 0) { - for (int i = 0; i < N; ++i) { + for (MAT_SIZE_T i = 0; i < N; ++i) { std::cout << BB[i] << ' '; } std::cout << std::endl; @@ -121,14 +123,14 @@ int main() std::cerr << "Something went wrong in debsv_()\n"; } - for (int i = 0; i < N; ++i) { + for (MAT_SIZE_T i = 0; i < N; ++i) { BB[i] = i; } dgbsv_(&N, &kl, &ku, &nrhs, &AB[0], &ldab, &ipiv[0], &BB[0], &ldb, &info); if (info == 0) { - for (int i = 0; i < N; ++i) { + for (MAT_SIZE_T i = 0; i < N; ++i) { std::cout << BB[i] << ' '; } std::cout << std::endl; From d03c4686239c047f014cfe28567018c4446f03c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Fri, 24 Aug 2012 18:26:26 +0200 Subject: [PATCH 21/38] Remove a derelict statement inherited from original implementation. Disabled by default, this statement attempted to pass a std::istream to function std::fclose() which is meaningless and should not be enabled at any time--even for a MATLAB-related build. --- opm/core/utility/parameters/ParameterGroup.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/opm/core/utility/parameters/ParameterGroup.cpp b/opm/core/utility/parameters/ParameterGroup.cpp index 30e7b8e4..3fcbf8d2 100644 --- a/opm/core/utility/parameters/ParameterGroup.cpp +++ b/opm/core/utility/parameters/ParameterGroup.cpp @@ -4,7 +4,7 @@ // // Created: Tue Jun 2 19:13:17 2009 // -// Author(s): Bård Skaflestad +// Author(s): BÃ¥rd Skaflestad // Atgeirr F Rasmussen // // $Date$ @@ -139,9 +139,6 @@ namespace Opm { } } } - #ifdef MATLAB_MEX_FILE - fclose(is); - #endif } void ParameterGroup::writeParam(const std::string& param_filename) const { From 58ad0863cd4d613165ca73a79bf445f2db2059e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Fri, 24 Aug 2012 19:16:31 +0200 Subject: [PATCH 22/38] Reference from canonical location. The header was removed from this directory upon import from the preexisting "opmtransport" repository. --- opm/core/transport/reorder/reordersequence.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/opm/core/transport/reorder/reordersequence.cpp b/opm/core/transport/reorder/reordersequence.cpp index 29f3a0aa..0e7b9f94 100644 --- a/opm/core/transport/reorder/reordersequence.cpp +++ b/opm/core/transport/reorder/reordersequence.cpp @@ -1,11 +1,11 @@ /* Copyright 2011 (c) Jostein R. Natvig */ +#include + #ifdef MATLAB_MEX_FILE -#include "grid.h" #include "reordersequence.h" #include "tarjan.h" #else -#include #include #include #endif From 86e25f127c3983cf26c05eada8321135abb9bc73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Fri, 24 Aug 2012 19:28:08 +0200 Subject: [PATCH 23/38] Remove MEX support. This has not been used in a long time, and actually prevents using the module in MEX. --- opm/core/transport/reorder/nlsolvers.c | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/opm/core/transport/reorder/nlsolvers.c b/opm/core/transport/reorder/nlsolvers.c index df95d2b3..ae372eb2 100644 --- a/opm/core/transport/reorder/nlsolvers.c +++ b/opm/core/transport/reorder/nlsolvers.c @@ -26,24 +26,8 @@ SOFTWARE. #include #include -#ifdef MATLAB_MEX_FILE -#include "nlsolvers.h" - -#include -extern int interrupt_signal; -#define print mexPrintf -#define malloc mxMalloc -#define calloc mxCalloc -#define realloc mxRealloc -#define free mxFree - -#else /* MATLAB_MEX_FILE */ - -#define print printf #include -#endif /* MATLAB_MEX_FILE */ - static const char no_root_str[]= " In %s:\n" " With G(%5f) =% 5f, G(%5f) =% 5f, G(x) is not bracketed!\n"; @@ -100,7 +84,7 @@ ridders (double (*G)(double, void*), void *data, struct NonlinearSolverCtrl *ctr if (G0*G1 > 0) { - print(no_root_str, "ridder", s0, G0, s1, G1); + printf(no_root_str, "ridder", s0, G0, s1, G1); return -1.0; } @@ -157,7 +141,7 @@ ridders (double (*G)(double, void*), void *data, struct NonlinearSolverCtrl *ctr } else { - print("In ridder:\nG0=%10.10f, G1=%10.10f, " + printf("In ridder:\nG0=%10.10f, G1=%10.10f, " "G3=%10.10f\n", G0, G1, G3); } s2 = 0.5*(s0+s1); @@ -199,7 +183,7 @@ regulafalsi (double (*G)(double, void*), void *data, struct NonlinearSolverCtrl if (G0*G1 > 0) { - print(no_root_str, "regulafalsi", s0, G0, s1, G1); + printf(no_root_str, "regulafalsi", s0, G0, s1, G1); return -1.0; } @@ -282,7 +266,7 @@ bisection (double (*G)(double, void*), void *data, struct NonlinearSolverCtrl *c if (G0*G1 > 0.0) { - print(no_root_str, "bisection", s0, G0, s1, G1); + printf(no_root_str, "bisection", s0, G0, s1, G1); return -1.0; } @@ -312,7 +296,7 @@ bisection (double (*G)(double, void*), void *data, struct NonlinearSolverCtrl *c } if (ctrl->iterations >= ctrl->maxiterations) { - print("Warning: convergence criterion not met\n"); + printf("Warning: convergence criterion not met\n"); } ctrl->residual = Gn; return sn; From eb40bdee130075997ba682929a7914fd685a8e9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Fri, 24 Aug 2012 19:44:13 +0200 Subject: [PATCH 24/38] Simplify the logic to support --with-unit*=speciallib syntax This change implements the approach of (e.g.,) ax_boost_system.m4, but may lose some of the initial refinements. In that case, we will have to refine this code. --- m4/ax_boost_unit_test_framework.m4 | 43 +++++++++++++++++------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/m4/ax_boost_unit_test_framework.m4 b/m4/ax_boost_unit_test_framework.m4 index 0cee8baa..424b3162 100644 --- a/m4/ax_boost_unit_test_framework.m4 +++ b/m4/ax_boost_unit_test_framework.m4 @@ -102,27 +102,32 @@ AC_DEFUN([AX_BOOST_UNIT_TEST_FRAMEWORK], fi else link_unit_test_framework="no" - saved_ldflags="${LDFLAGS}" + saved_ldflags="${LDFLAGS}" for ax_lib in boost_unit_test_framework-$ax_boost_user_unit_test_framework_lib $ax_boost_user_unit_test_framework_lib ; do - if test "x$link_unit_test_framework" = "xyes"; then - break; - fi - for unittest_library in `ls $BOOSTLIBDIR/lib${ax_lib}.so* $BOOSTLIBDIR/lib${ax_lib}.a* 2>/dev/null` ; do - if test -r $unittest_library ; then - libextension=`echo $unittest_library | sed 's,.*/,,' | sed -e 's;^lib\(boost_unit_test_framework.*\)\.so.*$;\1;' -e 's;^lib\(boost_unit_test_framework.*\)\.a*$;\1;'` - ax_lib=${libextension} - link_unit_test_framework="yes" - else - link_unit_test_framework="no" - fi + #if test "x$link_unit_test_framework" = "xyes"; then + # break; + #fi + #for unittest_library in `ls $BOOSTLIBDIR/lib${ax_lib}.so* $BOOSTLIBDIR/lib${ax_lib}.a* 2>/dev/null` ; do + #if test -r $unittest_library ; then + # libextension=`echo $unittest_library | sed 's,.*/,,' | sed -e 's;^lib\(boost_unit_test_framework.*\)\.so.*$;\1;' -e 's;^lib\(boost_unit_test_framework.*\)\.a*$;\1;'` + # ax_lib=${libextension} + # link_unit_test_framework="yes" + # else + # link_unit_test_framework="no" + # fi +# + # if test "x$link_unit_test_framework" = "xyes"; then + # BOOST_UNIT_TEST_FRAMEWORK_LIB="-l$ax_lib" + # AC_SUBST(BOOST_UNIT_TEST_FRAMEWORK_LIB) + # break + # fi - if test "x$link_unit_test_framework" = "xyes"; then - BOOST_UNIT_TEST_FRAMEWORK_LIB="-l$ax_lib" - AC_SUBST(BOOST_UNIT_TEST_FRAMEWORK_LIB) - break - fi - done - done + # done + + AC_CHECK_LIB($ax_lib, [exit], + [BOOST_UNIT_TEST_FRAMEWORK_LIB="-l$ax_lib"; AC_SUBST([BOOST_UNIT_TEST_FRAMEWORK_LIB]) link_unit_test_framework="yes"; break], + [link_unit_test_framework="no"]) + done fi if test "x$ax_lib" = "x"; then AC_MSG_ERROR(Could not find a version of the library!) From 4422bdfb3ec40aa47710bb993bd1528bd2a57be9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Fri, 24 Aug 2012 19:53:15 +0200 Subject: [PATCH 25/38] Expose the Boost library directory to the build system. This enables explicitly encoding the directory, e.g., in the OPM-Core run-path. This, in turn, reduces the burden on library clients that would otherwise have to satisfy library link requirements in addition to any other link requirements they might have. --- m4/opm_boost_base.m4 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/m4/opm_boost_base.m4 b/m4/opm_boost_base.m4 index 430f9abb..4f4ea066 100644 --- a/m4/opm_boost_base.m4 +++ b/m4/opm_boost_base.m4 @@ -103,6 +103,7 @@ if test "x$want_boost" = "xyes"; then for ac_boost_path_tmp in $libsubdirs; do if test -d "$ac_boost_path"/"$ac_boost_path_tmp" ; then OPM_BOOST_LDFLAGS="-L$ac_boost_path/$ac_boost_path_tmp" + OPM_BOOST_LIBDIR="${ac_boost_path}/${ac_boost_path_tmp}" break fi done @@ -114,6 +115,7 @@ if test "x$want_boost" = "xyes"; then done OPM_BOOST_LDFLAGS="-L$ac_boost_path_tmp/$libsubdir" OPM_BOOST_CPPFLAGS="-I$ac_boost_path_tmp/include" + OPM_BOOST_LIBDIR="${ac_boost_path_tmp}/${libsubdir}" break; fi done @@ -123,6 +125,7 @@ if test "x$want_boost" = "xyes"; then dnl --with-boost-libdir parameter if test "$ac_boost_lib_path" != ""; then OPM_BOOST_LDFLAGS="-L$ac_boost_lib_path" + OPM_BOOST_LIBDIR="${ac_boost_lib_path}" fi CPPFLAGS_SAVED="$CPPFLAGS" @@ -191,6 +194,7 @@ if test "x$want_boost" = "xyes"; then if ls "$best_path/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi done OPM_BOOST_LDFLAGS="-L$best_path/$libsubdir" + OPM_BOOST_LIBDIR="$best_path/$libsubdir" fi fi @@ -207,6 +211,7 @@ if test "x$want_boost" = "xyes"; then AC_MSG_NOTICE(We will use a staged boost library from $BOOST_ROOT) OPM_BOOST_CPPFLAGS="-I$BOOST_ROOT" OPM_BOOST_LDFLAGS="-L$BOOST_ROOT/stage/$libsubdir" + OPM_BOOST_LIBDIR="$BOOST_ROOT/stage/$libsubdir" fi fi fi @@ -248,6 +253,7 @@ if test "x$want_boost" = "xyes"; then else AC_SUBST([OPM_BOOST_CPPFLAGS]) AC_SUBST([OPM_BOOST_LDFLAGS]) + AC_SUBST([OPM_BOOST_LIBDIR]) AC_DEFINE([OPM_HAVE_BOOST], [1], [define if the Boost library is available]) # execute ACTION-IF-FOUND (if present): ifelse([$2], , :, [$2]) From 2a4fed5c2802ed45454c011c5b7c8c6e94516dbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Fri, 24 Aug 2012 20:15:57 +0200 Subject: [PATCH 26/38] Encode Boost library location in OPM-Core's run-path. Specifically, use the OPM_BOOST_LIBDIR variable created in commit 5c97e512 and Libtool's "-R" link-time switch to encode the library location within OPM-Core's run-path. This simplifies using the library, because the onus of satisfying the library's link-time requirements is removed from the client. A second refinement puts the additional link-requirements (i.e., "-l" and "-L" options) within the *_LIBADD primary. This moves the libraries from the middle to the end of the link statement. middle. --- Makefile.am | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index c1c85dec..9d18f4cb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -19,7 +19,10 @@ $(OPM_BOOST_CPPFLAGS) # (transitively) convey inter-library dependency information. lib_libopmcore_la_LDFLAGS = \ -$(OPM_BOOST_LDFLAGS) \ +-R $(OPM_BOOST_LIBDIR) \ +$(OPM_BOOST_LDFLAGS) + +lib_libopmcore_la_LIBADD = \ $(BOOST_FILESYSTEM_LIB) \ $(BOOST_SYSTEM_LIB) \ $(BOOST_DATE_TIME_LIB) \ From 0adb113669264e9f03b31f5b2b42e196873fea18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Fri, 24 Aug 2012 20:22:07 +0200 Subject: [PATCH 27/38] Obtain Boost libraries from libopmcore.la . Specifically, commit ff4f709e made the support for transitively conveying interlibrary dependencies onto clients of OPM-Core more robust. As a consequence, we no longer need to explicitly link in the Boost.System or Boost.Filesystem libraries to use the software contained therein. --- examples/Makefile.am | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/Makefile.am b/examples/Makefile.am index 6d664bdf..d43df479 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -5,9 +5,7 @@ $(OPM_BOOST_CPPFLAGS) # All targets link to the library LDADD = \ -$(top_builddir)/lib/libopmcore.la \ -$(BOOST_FILESYSTEM_LIB) \ -$(BOOST_SYSTEM_LIB) +$(top_builddir)/lib/libopmcore.la # ---------------------------------------------------------------------- # Declare products (i.e., the example programs). From e870c7726e5a8abe30ada7045991c6a95c129526 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Tue, 28 Aug 2012 16:03:26 +0200 Subject: [PATCH 28/38] Add a utility for creating a grid from textual representation. There is little to no error checking, and the importer assumes that the grid is serialised more or less directly from the grid structure. Intended use: Testing on non-uniform grids created in MRST. --- opm/core/grid.c | 397 ++++++++++++++++++++++++++++++++++++++++++++++++ opm/core/grid.h | 11 ++ 2 files changed, 408 insertions(+) diff --git a/opm/core/grid.c b/opm/core/grid.c index 9fa4cd67..bb7de1bc 100644 --- a/opm/core/grid.c +++ b/opm/core/grid.c @@ -18,7 +18,12 @@ */ #include + +#include +#include +#include #include +#include void @@ -135,3 +140,395 @@ allocate_grid(size_t ndims , return G; } + + +#define GRID_NDIMS 0 +#define GRID_NCELLS 1 +#define GRID_NFACES 2 +#define GRID_NNODES 3 +#define GRID_NFACENODES 4 +#define GRID_NCELLFACES 5 + + +static void +input_error(FILE *fp, const char * const err) +{ + int save_errno = errno; + + if (ferror(fp)) { + fprintf(stderr, "%s: %s\n", err, strerror(save_errno)); + clearerr(fp); + } + else if (feof(fp)) { + fprintf(stderr, "%s: End-of-file\n", err); + } + + errno = save_errno; +} + + +static struct UnstructuredGrid * +allocate_grid_from_file(FILE *fp, int *has_tag, int *has_indexmap) +{ + struct UnstructuredGrid *G; + + int save_errno; + unsigned long tmp; + size_t dimens[6], i; + + save_errno = errno; + + i = 0; + while ((i < 6) && (fscanf(fp, " %lu", &tmp) == 1)) { + dimens[i] = tmp; + + i += 1; + } + + if (i == 6) { + if (fscanf(fp, "%d %d", has_tag, has_indexmap) == 2) { + G = allocate_grid(dimens[GRID_NDIMS] , + dimens[GRID_NCELLS] , + dimens[GRID_NFACES] , + dimens[GRID_NFACENODES], + dimens[GRID_NCELLFACES], + dimens[GRID_NNODES] ); + + if (G != NULL) { + if (! *has_tag) { + free(G->cell_facetag); + G->cell_facetag = NULL; + } + + if (*has_indexmap) { + G->global_cell = + malloc(dimens[GRID_NCELLS] * sizeof *G->global_cell); + + /* Allocation failure checked elsewhere. */ + } + + G->number_of_cells = (int) dimens[GRID_NCELLS]; + G->number_of_faces = (int) dimens[GRID_NFACES]; + G->number_of_nodes = (int) dimens[GRID_NNODES]; + G->dimensions = (int) dimens[GRID_NDIMS]; + + i = 0; + while ((i < dimens[GRID_NDIMS]) && + (fscanf(fp, "%d", & G->cartdims[ i ]) == 1)) { + i += 1; + } + + if (i < dimens[GRID_NDIMS]) { + input_error(fp, "Unable to read Cartesian dimensions"); + + destroy_grid(G); + G = NULL; + } + else { + /* Account for dimens[GRID_DIMS] < 3 */ + size_t n = (sizeof G->cartdims) / (sizeof G->cartdims[0]); + for (; i < n; i++) { G->cartdims[ i ] = 1; } + } + } + } + else { + input_error(fp, "Unable to read grid predicates"); + + G = NULL; + } + } + else { + input_error(fp, "Unable to read grid dimensions"); + + G = NULL; + } + + errno = save_errno; + + return G; +} + + +static int +read_grid_nodes(FILE *fp, struct UnstructuredGrid *G) +{ + int save_errno; + size_t i, n; + + save_errno = errno; + + n = G->dimensions; + n *= G->number_of_nodes; + + i = 0; + while ((i < n) && + (fscanf(fp, " %lf", & G->node_coordinates[ i ]) == 1)) { + i += 1; + } + + if (i < n) { + input_error(fp, "Unable to read node coordinates"); + } + + errno = save_errno; + + return i == n; +} + + +static int +read_grid_faces(FILE *fp, struct UnstructuredGrid *G) +{ + int save_errno, ok; + size_t nf, nfn, i; + + save_errno = errno; + + nf = G->number_of_faces; + + /* G->face_nodepos */ + i = 0; + while ((i < nf + 1) && + (fscanf(fp, " %d", & G->face_nodepos[ i ]) == 1)) { + i += 1; + } + ok = i == nf + 1; + + if (! ok) { + input_error(fp, "Unable to read node indirection array"); + } + else { + /* G->face_nodes */ + nfn = G->face_nodepos[ nf ]; + + i = 0; + while ((i < nfn) && (fscanf(fp, " %d", & G->face_nodes[ i ]) == 1)) { + i += 1; + } + + ok = i == nfn; + if (! ok) { + input_error(fp, "Unable to read face-nodes"); + } + } + + if (ok) { + /* G->face_cells */ + i = 0; + while ((i < 2 * nf) && (fscanf(fp, " %d", & G->face_cells[ i ]) == 1)) { + i += 1; + } + + ok = i == 2 * nf; + if (! ok) { + input_error(fp, "Unable to read neighbourship"); + } + } + + if (ok) { + /* G->face_areas */ + i = 0; + while ((i < nf) && (fscanf(fp, " %lf", & G->face_areas[ i ]) == 1)) { + i += 1; + } + + ok = i == nf; + if (! ok) { + input_error(fp, "Unable to read face areas"); + } + } + + if (ok) { + /* G->face_centroids */ + size_t n; + + n = G->dimensions; + n *= nf; + + i = 0; + while ((i < n) && (fscanf(fp, " %lf", & G->face_centroids[ i ]) == 1)) { + i += 1; + } + + ok = i == n; + if (! ok) { + input_error(fp, "Unable to read face centroids"); + } + } + + if (ok) { + /* G->face_normals */ + size_t n; + + n = G->dimensions; + n *= nf; + + i = 0; + while ((i < n) && (fscanf(fp, " %lf", & G->face_normals[ i ]) == 1)) { + i += 1; + } + + ok = i == n; + if (! ok) { + input_error(fp, "Unable to read face normals"); + } + } + + errno = save_errno; + + return ok; +} + + +static int +read_grid_cells(FILE *fp, int has_tag, int has_indexmap, + struct UnstructuredGrid *G) +{ + int save_errno, ok; + size_t nc, ncf, i; + + save_errno = errno; + + nc = G->number_of_cells; + + /* G->cell_facepos */ + i = 0; + while ((i < nc + 1) && (fscanf(fp, " %d", & G->cell_facepos[ i ]) == 1)) { + i += 1; + } + ok = i == nc + 1; + + if (! ok) { + input_error(fp, "Unable to read face indirection array"); + } + else { + /* G->cell_faces (and G->cell_facetag if applicable) */ + ncf = G->cell_facepos[ nc ]; + i = 0; + + if (has_tag) { + assert (G->cell_facetag != NULL); + + while ((i < ncf) && + (fscanf(fp, " %d %d", + & G->cell_faces [ i ], + & G->cell_facetag[ i ]) == 2)) { + i += 1; + } + } + else { + while ((i < ncf) && + (fscanf(fp, " %d", & G->cell_faces[ i ]) == 1)) { + i += 1; + } + } + + ok = i == ncf; + if (! ok) { + input_error(fp, "Unable to read cell-faces"); + } + } + + if (ok) { + /* G->global_cell if applicable */ + if (has_indexmap) { + i = 0; + + if (G->global_cell != NULL) { + while ((i < nc) && + (fscanf(fp, " %d", & G->global_cell[ i ]) == 1)) { + i += 1; + } + } + else { + int discard; + + while ((i < nc) && (fscanf(fp, " %d", & discard) == 1)) { + i += 1; + } + } + } + else { + assert (G->global_cell == NULL); + i = nc; + } + + ok = i == nc; + if (! ok) { + input_error(fp, "Unable to read global cellmap"); + } + } + + if (ok) { + /* G->cell_volumes */ + i = 0; + while ((i < nc) && (fscanf(fp, " %lf", & G->cell_volumes[ i ]) == 1)) { + i += 1; + } + + ok = i == nc; + if (! ok) { + input_error(fp, "Unable to read cell volumes"); + } + } + + if (ok) { + /* G->cell_centroids */ + size_t n; + + n = G->dimensions; + n *= nc; + + i = 0; + while ((i < n) && (fscanf(fp, " %lf", & G->cell_centroids[ i ]) == 1)) { + i += 1; + } + + ok = i == n; + if (! ok) { + input_error(fp, "Unable to read cell centroids"); + } + } + + errno = save_errno; + + return ok; +} + + +struct UnstructuredGrid * +read_grid(const char *fname) +{ + struct UnstructuredGrid *G; + FILE *fp; + + int save_errno; + int has_tag, has_indexmap, ok; + + save_errno = errno; + + fp = fopen(fname, "rt"); + if (fp != NULL) { + G = allocate_grid_from_file(fp, & has_tag, & has_indexmap); + + ok = G != NULL; + + if (ok) { ok = read_grid_nodes(fp, G); } + if (ok) { ok = read_grid_faces(fp, G); } + if (ok) { ok = read_grid_cells(fp, has_tag, has_indexmap, G); } + + if (! ok) { + destroy_grid(G); + G = NULL; + } + + fclose(fp); + } + else { + G = NULL; + } + + errno = save_errno; + + return G; +} diff --git a/opm/core/grid.h b/opm/core/grid.h index 841ea8e2..37b074d4 100644 --- a/opm/core/grid.h +++ b/opm/core/grid.h @@ -273,6 +273,17 @@ allocate_grid(size_t ndims , size_t ncellfaces, size_t nnodes ); + +/** + * Import a grid from a character representation stored in file. + * + * @param[in] fname File name. + * @return Fully formed UnstructuredGrid with all fields allocated and filled. + * Returns @c NULL in case of allocation failure. + */ +struct UnstructuredGrid * +read_grid(const char *fname); + #ifdef __cplusplus } #endif From 5b9c8355105e5c1901e86480097c7acb03e1195d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Tue, 28 Aug 2012 16:05:44 +0200 Subject: [PATCH 29/38] Add a simple test to demonstrate grid input. Should be extended to test that the input is sane, too. --- tests/Makefile.am | 1 + tests/test_read_grid.c | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 tests/test_read_grid.c diff --git a/tests/Makefile.am b/tests/Makefile.am index a82a1dc3..f23270e7 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -17,6 +17,7 @@ sparsevector_test \ test_cartgrid \ test_column_extract \ test_lapack \ +test_read_grid \ test_read_vag \ test_readpolymer \ test_sf2p \ diff --git a/tests/test_read_grid.c b/tests/test_read_grid.c new file mode 100644 index 00000000..c739771a --- /dev/null +++ b/tests/test_read_grid.c @@ -0,0 +1,25 @@ +/* + * test_read_grid.c + * + * Created on: Aug 28, 2012 + * Author: bska + */ + +#include + +#include +#include + +int +main(void) +{ + struct UnstructuredGrid *G1, *G2; + + G1 = read_grid("cart_grid_2d.txt"); + G2 = create_grid_cart2d(2, 2); + + destroy_grid(G2); + destroy_grid(G1); + + return 0; +} From 8694794aae212ee0b1a81585af001d0f3fef48bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Spjelkavik?= Date: Wed, 29 Aug 2012 11:28:23 +0200 Subject: [PATCH 30/38] Added private member function getNumericErtFields --- opm/core/eclipse/EclipseGridParser.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/opm/core/eclipse/EclipseGridParser.hpp b/opm/core/eclipse/EclipseGridParser.hpp index 9f66e9ae..92889a13 100644 --- a/opm/core/eclipse/EclipseGridParser.hpp +++ b/opm/core/eclipse/EclipseGridParser.hpp @@ -196,6 +196,7 @@ private: SpecialFieldPtr cloneSpecialField(const std::string& fieldname, const std::tr1::shared_ptr original); void readImpl(std::istream& is); + void getNumericErtFields(const std::string& filename); std::string directory_; From 42944315849e765ca3dbbb95db21583ba81a0e57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Spjelkavik?= Date: Wed, 29 Aug 2012 13:36:57 +0200 Subject: [PATCH 31/38] Defined private member function 'getNumericErtFields' in class 'EclipseGridParser' The function stores data from one file from keyword IMPORT. The file in 'fortio' format is read by ERT-functions. --- opm/core/eclipse/EclipseGridParser.cpp | 57 ++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/opm/core/eclipse/EclipseGridParser.cpp b/opm/core/eclipse/EclipseGridParser.cpp index b4ea9ee3..4c8cc492 100644 --- a/opm/core/eclipse/EclipseGridParser.cpp +++ b/opm/core/eclipse/EclipseGridParser.cpp @@ -801,4 +801,61 @@ void EclipseGridParser::computeUnits() } } +#if USE_ERT +// Read an imported fortio data file using Ert. +// Data stored in 'integer_field_map_' and 'floating_field_map_'. +void EclipseGridParser::getNumericErtFields(const string& filename) +{ + // Read file + ecl_file_type * ecl_file = ecl_file_open(filename.c_str()); + const int num_kw = ecl_file_get_size(ecl_file); + std::vector double_vec; + std::vector int_vec; + for (int i=0; i Date: Sun, 30 Sep 2012 15:42:13 +0200 Subject: [PATCH 34/38] Update ert test program to make it compile again. --- tests/test_ert.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/tests/test_ert.cpp b/tests/test_ert.cpp index d2921f67..ef18216c 100644 --- a/tests/test_ert.cpp +++ b/tests/test_ert.cpp @@ -34,7 +34,7 @@ using namespace std; - +static void cell_nodes(const UnstructuredGrid * c_grid , int cell , std::vector& nodes) { int face_offset = c_grid->cell_facepos[cell]; int num_faces = c_grid->cell_facepos[cell + 1] - face_offset; @@ -80,7 +80,7 @@ void cell_nodes(const UnstructuredGrid * c_grid , int cell , std::vector& n } - +static void eclExport(Opm::GridManager& grid) { const UnstructuredGrid * c_grid = grid.c_grid(); @@ -119,7 +119,7 @@ void eclExport(Opm::GridManager& grid) { int ** coords; float ** corners; - float * mapaxes = NULL; + // float * mapaxes = NULL; std::vector nodes; corners = (float **) malloc( num_coords * sizeof * corners ); @@ -244,7 +244,7 @@ ecl_grid_type * create_ecl_grid( const struct UnstructuredGrid * g) { -int main(int argc , char **argv) +int main(int /*argc*/ , char **argv) { std::string filename( argv[1] ); boost::scoped_ptr grid; @@ -254,8 +254,6 @@ int main(int argc , char **argv) //eclParser.saveEGRID_INIT("/tmp" , "OPM" ); grid.reset(new Opm::GridManager(eclParser)); - const int* gc = grid->c_grid()->global_cell; - std::vector global_cell(gc, gc + grid->c_grid()->number_of_cells); - props.reset(new Opm::IncompPropertiesFromDeck(eclParser , global_cell)); + props.reset(new Opm::IncompPropertiesFromDeck(eclParser , *grid->c_grid())); } From 2e99dd48dc5a9cd8de7703823a71bc6eed104a08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Mon, 1 Oct 2012 17:37:18 +0200 Subject: [PATCH 35/38] Don't compare signed to unsigned integer types. This avoids recalcitrant objections from the compiler. --- opm/core/eclipse/EclipseGridParser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opm/core/eclipse/EclipseGridParser.cpp b/opm/core/eclipse/EclipseGridParser.cpp index 9b0352b2..da505b63 100644 --- a/opm/core/eclipse/EclipseGridParser.cpp +++ b/opm/core/eclipse/EclipseGridParser.cpp @@ -884,7 +884,7 @@ ecl_kw_type * EclipseGridParser::newEclKW(const std::string &keyword , ecl_type_ ecl_kw_set_memcpy_data( ecl_kw , &data[0]); } else if (ecl_type == ECL_FLOAT_TYPE) { ecl_kw = ecl_kw_alloc( keyword.c_str() , data.size() , ecl_type ); - for (int i=0; i < data.size(); i++) + for (std::vector::size_type i=0; i < data.size(); i++) ecl_kw_iset_float( ecl_kw , i , data[i] ); } } From 416086db2e2c8337802ba2a4993054eda864dcc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A5rd=20Skaflestad?= Date: Thu, 4 Oct 2012 21:09:47 +0200 Subject: [PATCH 36/38] New function clone_wells() Used to create a deep copy (clone) of an existing Wells object. While here, add test case for common Wells object operations. --- opm/core/newwells.c | 75 ++++++++++++++++ opm/core/newwells.h | 13 +++ tests/Makefile.am | 4 + tests/test_wells.cpp | 205 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 297 insertions(+) create mode 100644 tests/test_wells.cpp diff --git a/opm/core/newwells.c b/opm/core/newwells.c index ac416e5a..c28e8566 100644 --- a/opm/core/newwells.c +++ b/opm/core/newwells.c @@ -593,3 +593,78 @@ clear_well_controls(int well_index, struct Wells *W) W->ctrls[well_index]->num = 0; } } + + +/* ---------------------------------------------------------------------- */ +struct Wells * +clone_wells(const struct Wells *W) +/* ---------------------------------------------------------------------- */ +{ + int c, np, nperf, ok, pos, w; + double target; + const int *cells; + const double *WI, *comp_frac, *distr; + enum WellControlType type; + const struct WellControls *ctrls; + + struct Wells *ret; + + if (W == NULL) { + ret = NULL; + } + else { + np = W->number_of_phases; + ret = create_wells(W->number_of_phases, W->number_of_wells, + W->well_connpos[ W->number_of_wells ]); + + if (ret != NULL) { + pos = W->well_connpos[ 0 ]; + ok = 1; + + for (w = 0; ok && (w < W->number_of_wells); w++) { + nperf = W->well_connpos[w + 1] - pos; + cells = W->well_cells + pos; + + WI = W->WI != NULL ? W->WI + pos : NULL; + comp_frac = W->comp_frac != NULL ? W->comp_frac + w*np : NULL; + + ok = add_well(W->type[ w ], W->depth_ref[ w ], nperf, + comp_frac, cells, WI, W->name[ w ], ret); + + /* Capacity should be sufficient from create_wells() */ + assert (ok); + + ctrls = W->ctrls[ w ]; + + if (ok) { + ok = well_controls_reserve(ctrls->num, np, ret->ctrls[ w ]); + + for (c = 0; ok && (c < ctrls->num); c++) { + type = ctrls->type [ c ]; + target = ctrls->target[ c ]; + distr = & ctrls->distr [ c * np ]; + + ok = append_well_controls(type, target, distr, w, ret); + + /* Capacity *should* be sufficient from + * well_controls_reserve() */ + assert (ok); + } + } + + if (ok) { + set_current_control(w, ctrls->current, ret); + } + + pos = W->well_connpos[w + 1]; + } + + if (! ok) { + destroy_wells(ret); + ret = NULL; + } + } + } + + return ret; +} diff --git a/opm/core/newwells.h b/opm/core/newwells.h index f16675b6..20cfce61 100644 --- a/opm/core/newwells.h +++ b/opm/core/newwells.h @@ -235,6 +235,19 @@ void destroy_wells(struct Wells *W); +/** + * Create a deep-copy (i.e., clone) of an existing Wells object, including its + * controls. + * + * @param[in] W Existing Wells object. + * @return Complete clone of the input object. Dispose of resources using + * function destroy_wells() when no longer needed. Returns @c NULL in case of + * allocation failure. + */ +struct Wells * +clone_wells(const struct Wells *W); + + #ifdef __cplusplus } #endif diff --git a/tests/Makefile.am b/tests/Makefile.am index b1e70503..7bca7d66 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -23,6 +23,7 @@ test_read_grid \ test_read_vag \ test_readpolymer \ test_sf2p \ +test_wells \ test_writeVtkData \ unit_test @@ -59,6 +60,9 @@ test_sf2p_SOURCES = test_sf2p.cpp test_writeVtkData_SOURCES = test_writeVtkData.cpp +test_wells_SOURCES = test_wells.cpp +test_wells_LDADD = $(LDADD) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) + unit_test_SOURCES = unit_test.cpp diff --git a/tests/test_wells.cpp b/tests/test_wells.cpp new file mode 100644 index 00000000..4f8ad7bb --- /dev/null +++ b/tests/test_wells.cpp @@ -0,0 +1,205 @@ +/* + 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 . +*/ + +#include + +#if HAVE_DYNAMIC_BOOST_TEST +#define BOOST_TEST_DYN_LINK +#endif + +#define NVERBOSE // Suppress own messages when throw()ing + +#define BOOST_TEST_MODULE WellsModuleTest +#include + +#include + +#include +#include +#include + +BOOST_AUTO_TEST_CASE(Construction) +{ + const int nphases = 2; + const int nwells = 2; + const int nperfs = 2; + + boost::shared_ptr W(create_wells(nphases, nwells, nperfs), + destroy_wells); + + if (W) { + int cells[] = { 0, 9 }; + double WI = 1.0; + const double ifrac[] = { 1.0, 0.0 }; + + const bool ok0 = add_well(INJECTOR, 0.0, 1, &ifrac[0], &cells[0], + &WI, "INJECTOR", W.get()); + + const double pfrac[] = { 0.0, 0.0 }; + const bool ok1 = add_well(PRODUCER, 0.0, 1, &pfrac[0], &cells[1], + &WI, "PRODUCER", W.get()); + + if (ok0 && ok1) { + BOOST_CHECK_EQUAL(W->number_of_phases, nphases); + BOOST_CHECK_EQUAL(W->number_of_wells , nwells ); + + BOOST_CHECK_EQUAL(W->well_connpos[0], 0); + BOOST_CHECK_EQUAL(W->well_connpos[1], 1); + BOOST_CHECK_EQUAL(W->well_connpos[W->number_of_wells], nperfs); + + BOOST_CHECK_EQUAL(W->well_cells[W->well_connpos[0]], cells[0]); + BOOST_CHECK_EQUAL(W->well_cells[W->well_connpos[1]], cells[1]); + + BOOST_CHECK_EQUAL(W->WI[W->well_connpos[0]], WI); + BOOST_CHECK_EQUAL(W->WI[W->well_connpos[1]], WI); + + using std::string; + BOOST_CHECK_EQUAL(string(W->name[0]), string("INJECTOR")); + BOOST_CHECK_EQUAL(string(W->name[1]), string("PRODUCER")); + } + } +} + + +BOOST_AUTO_TEST_CASE(Controls) +{ + const int nphases = 2; + const int nwells = 1; + const int nperfs = 2; + + boost::shared_ptr W(create_wells(nphases, nwells, nperfs), + destroy_wells); + + if (W) { + int cells[] = { 0 , 9 }; + double WI [] = { 1.0, 1.0 }; + const double ifrac[] = { 1.0, 0.0 }; + + const bool ok = add_well(INJECTOR, 0.0, nperfs, &ifrac[0], &cells[0], + &WI[0], "INJECTOR", W.get()); + + if (ok) { + const double distr[] = { 1.0, 0.0 }; + const bool ok1 = append_well_controls(BHP, 1, &distr[0], + 0, W.get()); + const bool ok2 = append_well_controls(SURFACE_RATE, 1, + &distr[0], 0, W.get()); + + if (ok1 && ok2) { + WellControls* ctrls = W->ctrls[0]; + + BOOST_CHECK_EQUAL(ctrls->num , 2); + BOOST_CHECK_EQUAL(ctrls->current, -1); + + set_current_control(0, 0, W.get()); + BOOST_CHECK_EQUAL(ctrls->current, 0); + + set_current_control(0, 1, W.get()); + BOOST_CHECK_EQUAL(ctrls->current, 1); + + BOOST_CHECK_EQUAL(ctrls->type[0], BHP); + BOOST_CHECK_EQUAL(ctrls->type[1], SURFACE_RATE); + + BOOST_CHECK_EQUAL(ctrls->target[0], 1.0); + BOOST_CHECK_EQUAL(ctrls->target[1], 1.0); + } + } + } +} + + +BOOST_AUTO_TEST_CASE(Copy) +{ + const int nphases = 2; + const int nwells = 2; + const int nperfs = 2; + + boost::shared_ptr W1(create_wells(nphases, nwells, nperfs), + destroy_wells); + boost::shared_ptr W2; + + if (W1) { + int cells[] = { 0, 9 }; + const double WI = 1.0; + const double ifrac[] = { 1.0, 0.0 }; + + const bool ok0 = add_well(INJECTOR, 0.0, 1, &ifrac[0], &cells[0], + &WI, "INJECTOR", W1.get()); + + const double pfrac[] = { 0.0, 0.0 }; + const bool ok1 = add_well(PRODUCER, 0.0, 1, &pfrac[0], &cells[1], + &WI, "PRODUCER", W1.get()); + + bool ok = ok0 && ok1; + for (int w = 0; ok && (w < W1->number_of_wells); ++w) { + const double distr[] = { 1.0, 0.0 }; + const bool okc1 = append_well_controls(BHP, 1, &distr[0], + w, W1.get()); + const bool okc2 = append_well_controls(SURFACE_RATE, 1, + &distr[0], w, + W1.get()); + + ok = okc1 && okc2; + } + + if (ok) { + W2.reset(clone_wells(W1.get()), destroy_wells); + } + } + + if (W2) { + BOOST_CHECK_EQUAL(W2->number_of_phases, W1->number_of_phases); + BOOST_CHECK_EQUAL(W2->number_of_wells , W1->number_of_wells ); + BOOST_CHECK_EQUAL(W2->well_connpos[0] , W1->well_connpos[0] ); + + for (int w = 0; w < W1->number_of_wells; ++w) { + using std::string; + BOOST_CHECK_EQUAL(string(W2->name[w]), string(W1->name[w])); + BOOST_CHECK_EQUAL( W2->type[w] , W1->type[w] ); + + BOOST_CHECK_EQUAL(W2->well_connpos[w + 1], + W1->well_connpos[w + 1]); + + for (int j = W1->well_connpos[w]; + j < W1->well_connpos[w + 1]; ++j) { + BOOST_CHECK_EQUAL(W2->well_cells[j], W1->well_cells[j]); + BOOST_CHECK_EQUAL(W2->WI [j], W1->WI [j]); + } + + BOOST_CHECK(W1->ctrls[w] != 0); + BOOST_CHECK(W2->ctrls[w] != 0); + + WellControls* c1 = W1->ctrls[w]; + WellControls* c2 = W2->ctrls[w]; + + BOOST_CHECK_EQUAL(c2->num , c1->num ); + BOOST_CHECK_EQUAL(c2->current, c1->current); + + for (int c = 0; c < c1->num; ++c) { + BOOST_CHECK_EQUAL(c2->type [c], c1->type [c]); + BOOST_CHECK_EQUAL(c2->target[c], c1->target[c]); + + for (int p = 0; p < W1->number_of_phases; ++p) { + BOOST_CHECK_EQUAL(c2->distr[c*W1->number_of_phases + p], + c1->distr[c*W1->number_of_phases + p]); + } + } + } + } +} From 0f549358a9ec27ae1a1d9414a157e0312040e3d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Fri, 12 Oct 2012 14:23:55 +0200 Subject: [PATCH 37/38] Squash warnings. --- tests/test_ert.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/test_ert.cpp b/tests/test_ert.cpp index ef18216c..282549d1 100644 --- a/tests/test_ert.cpp +++ b/tests/test_ert.cpp @@ -33,7 +33,7 @@ using namespace std; - +#if 0 static void cell_nodes(const UnstructuredGrid * c_grid , int cell , std::vector& nodes) { int face_offset = c_grid->cell_facepos[cell]; @@ -78,8 +78,9 @@ void cell_nodes(const UnstructuredGrid * c_grid , int cell , std::vector& n */ } } +#endif - +/* static void eclExport(Opm::GridManager& grid) { const UnstructuredGrid * c_grid = grid.c_grid(); @@ -184,7 +185,7 @@ void eclExport(Opm::GridManager& grid) { free( coords ); } } - +*/ /* From 863eae336895fcf1bf4ece7efc4eb81b9cb1ef4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Fri, 12 Oct 2012 14:25:53 +0200 Subject: [PATCH 38/38] Hook IMPORT keyword to function reading binary input. Make sure it compiles and links both with and without ert. --- opm/core/eclipse/EclipseGridParser.cpp | 27 ++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/opm/core/eclipse/EclipseGridParser.cpp b/opm/core/eclipse/EclipseGridParser.cpp index c1da9f65..746794db 100644 --- a/opm/core/eclipse/EclipseGridParser.cpp +++ b/opm/core/eclipse/EclipseGridParser.cpp @@ -58,6 +58,7 @@ #include #include #include +#include #endif using namespace std; @@ -151,6 +152,9 @@ namespace EclipseKeywords string include_keywords[] = { string("INCLUDE") }; const int num_include_keywords = sizeof(include_keywords) / sizeof(include_keywords[0]); + string import_keywords[] = { string("IMPORT") }; + const int num_import_keywords = sizeof(import_keywords) / sizeof(import_keywords[0]); + } // namespace EclipseKeywords @@ -164,6 +168,7 @@ namespace { IgnoreWithData, IgnoreNoData, Include, + Import, Unknown }; @@ -184,6 +189,8 @@ namespace { return IgnoreNoData; } else if (count(include_keywords, include_keywords + num_include_keywords, keyword)) { return Include; + } else if (count(import_keywords, import_keywords + num_import_keywords, keyword)) { + return Import; } else { return Unknown; } @@ -498,6 +505,14 @@ void EclipseGridParser::readImpl(istream& is) // is >> ignoreSlashLine; break; } + case Import: { + string import_filename = readString(is); + if (!directory_.empty()) { + import_filename = directory_ + '/' + import_filename; + } + getNumericErtFields(import_filename); + break; + } case Unknown: default: ignored_fields_.insert(keyword); @@ -552,6 +567,9 @@ void EclipseGridParser::convertToSI() do_convert = false; // Dimensionless keywords... } else if (key == "PRESSURE") { unit = units_.pressure; + } else if (key == "MAPAXES") { + MESSAGE("Not applying units to MAPAXES yet!"); + unit = 1.0; } else { THROW("Units for field " << key << " not specified. Cannon convert to SI."); } @@ -1054,13 +1072,16 @@ void EclipseGridParser::saveEGRID_INIT( const std::string& output_dir , const st } #endif -#if USE_ERT // Read an imported fortio data file using Ert. // Data stored in 'integer_field_map_' and 'floating_field_map_'. void EclipseGridParser::getNumericErtFields(const string& filename) { +#ifdef HAVE_ERT // Read file ecl_file_type * ecl_file = ecl_file_open(filename.c_str()); + if (ecl_file == NULL) { + THROW("Could not open IMPORTed file " << filename); + } const int num_kw = ecl_file_get_size(ecl_file); std::vector double_vec; std::vector int_vec; @@ -1108,7 +1129,9 @@ void EclipseGridParser::getNumericErtFields(const string& filename) } } ecl_file_close(ecl_file); +#else + THROW("Cannot use IMPORT keyword without ert library support. Reconfigure opm-core with --with-ert and recompile."); +#endif // HAVE_ERT } -#endif //USE_ERT } // namespace Opm