2023-08-11 15:23:19 +02:00
/*
Copyright 2018 SINTEF Digital, Mathematics and Cybernetics.
Copyright 2018 Equinor.
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 <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#define BOOST_TEST_MODULE TestLogOutputHelper
#include <boost/test/unit_test.hpp>
#include <opm/common/OpmLog/OpmLog.hpp>
#include <opm/common/OpmLog/StreamLog.hpp>
#include <opm/common/utility/String.hpp>
#include <opm/input/eclipse/Deck/Deck.hpp>
#include <opm/input/eclipse/EclipseState/EclipseState.hpp>
#include <opm/input/eclipse/Parser/Parser.hpp>
#include <opm/input/eclipse/Python/Python.hpp>
#include <opm/input/eclipse/Schedule/Schedule.hpp>
#include <opm/input/eclipse/Schedule/SummaryState.hpp>
#include <opm/simulators/flow/LogOutputHelper.hpp>
#include <memory>
#include <string>
2024-04-11 10:59:32 +02:00
template < int type >
struct LogFixture
{
LogFixture () {
Opm :: OpmLog :: addBackend ( "stream" ,
std :: make_shared < Opm :: StreamLog > ( str , type ));
}
~ LogFixture () {
Opm :: OpmLog :: removeBackend ( "stream" );
}
std :: stringstream str ;
};
/*
template<>
std::stringstream LogFixture<Opm::Log::MessageType::Warning>::str;
template<>
std::stringstream LogFixture<Opm::Log::MessageType::Note>::str;
*/
using LogNoteFixture = LogFixture < Opm :: Log :: MessageType :: Note > ;
using LogWarningFixture = LogFixture < Opm :: Log :: MessageType :: Warning > ;
2023-08-11 15:23:19 +02:00
namespace {
const std :: string input = R "(
RUNSPEC
FIELD
DIMENS
10 10 3 /
DX
300 * 1000 /
DY
300 * 1000 /
DZ
100 * 20 100 * 30 100 * 50 /
TOPS
100 * 8325 /
START -- 0
31 AUG 1993 /
SCHEDULE
WELSPECS
-- Item # : 1 2 3 4 5 6
' PROD ' ' G1 ' 10 10 8400 ' OIL ' /
' INJ ' ' G1 ' 1 1 8335 ' GAS ' /
/
WCONPROD
-- Item # : 1 2 3 4 5 9
' PROD ' ' OPEN ' ' ORAT ' 20000 4 * 1000 /
/
WCONINJE
-- Item # : 1 2 3 4 5 6 7
' INJ ' ' GAS ' ' OPEN ' ' RATE ' 100000 1 * 9014 /
/ ) ";
2023-12-15 12:18:34 +01:00
2023-08-11 15:23:19 +02:00
std :: string trimStream ( std :: stringstream & str )
{
char buffer [ 1024 ];
std :: string data ;
do {
str . getline ( buffer , 1024 , '\n' );
std :: string tmp ( buffer );
if ( ! tmp . empty ()) {
tmp = Opm :: trim_copy ( tmp );
data += tmp ;
data += '\n' ;
}
} while ( ! str . eof ());
return data ;
}
2023-12-15 12:18:34 +01:00
2023-08-11 15:23:19 +02:00
}
2024-04-11 10:59:32 +02:00
BOOST_FIXTURE_TEST_CASE ( Cumulative , LogNoteFixture )
2023-08-11 15:23:19 +02:00
{
const std :: string reference = R "(=================================================== CUMULATIVE PRODUCTION/INJECTION REPORT =========================================
: WELL : LOCATION : WELL : CTRL : OIL : WATER : GAS : Prod : OIL : WATER : GAS : INJ :
: NAME : ( I , J , K ) : TYPE : MODE : PROD : PROD : PROD : RES . VOL . : INJ : INJ : INJ : RES . VOL . :
: : : : : MSTB : MSTB : MMSCF : MRB : MSTB : MSTB : MMSCF : MRB :
====================================================================================================================================
: FIELD : : : : 1.0 : 2.0 : 3.0 : 4.0 : 5.0 : 6.0 : 7.0 : 8.0 :
: G1 : : : : 9.0 : 10.0 : 11.0 : 12.0 : 13.0 : 14.0 : 15.0 : 15.0 :
: PROD : 10 , 10 : PROD : ORAT : 16.0 : 17.0 : 18.0 : 19.0 : 20.0 : 21.0 : 22.0 : 23.0 :
: INJ : 1 , 1 : INJ : GRAT : 24.0 : 25.0 : 26.0 : 27.0 : 28.0 : 29.0 : 30.0 : 31.0 :
2023-12-08 13:44:33 +01:00
:--------:-----------:--------:----:-----------:-----------:-----------:-----------:-----------:-----------:-----------:-----------:
2023-08-11 15:23:19 +02:00
) ";
Opm :: Parser parser ;
auto python = std :: make_shared < Opm :: Python > ();
auto deck = parser . parseString ( input );
Opm :: EclipseGrid grid ( 10 , 10 , 3 );
Opm :: TableManager table ( deck );
Opm :: FieldPropsManager fp ( deck , Opm :: Phases { true , true , true }, grid , table );
Opm :: Runspec runspec ( deck );
Opm :: Schedule schedule ( deck , grid , fp , runspec , python );
Opm :: EclipseState eclState ( deck );
Opm :: SummaryState st ;
2023-12-08 13:44:33 +01:00
// Note: Cumulative gas values--e.g., FGPT--multiplied by an additional
// factor of 1000, for a total multiplicative factor of one million, in
// order to produce the expected balance sheet output in MM* units.
2023-08-11 15:23:19 +02:00
constexpr auto fields = std :: array {
std :: pair { "FOPT" , 1.0 },
std :: pair { "FWPT" , 2.0 },
2023-12-08 13:44:33 +01:00
std :: pair { "FGPT" , 3.0e3 },
2023-08-11 15:23:19 +02:00
std :: pair { "FVPT" , 4.0 },
std :: pair { "FOIT" , 5.0 },
std :: pair { "FWIT" , 6.0 },
2023-12-08 13:44:33 +01:00
std :: pair { "FGIT" , 7.0e3 },
2023-08-11 15:23:19 +02:00
std :: pair { "FVIT" , 8.0 },
std :: pair { "GOPT:G1" , 9.0 },
std :: pair { "GWPT:G1" , 10.0 },
2023-12-08 13:44:33 +01:00
std :: pair { "GGPT:G1" , 11.0e3 },
2023-08-11 15:23:19 +02:00
std :: pair { "GVPT:G1" , 12.0 },
std :: pair { "GOIT:G1" , 13.0 },
std :: pair { "GWIT:G1" , 14.0 },
2023-12-08 13:44:33 +01:00
std :: pair { "GGIT:G1" , 15.0e3 },
2023-08-11 15:23:19 +02:00
std :: pair { "GVIT:G1" , 15.0 },
std :: pair { "WOPT:PROD" , 16.0 },
std :: pair { "WWPT:PROD" , 17.0 },
2023-12-08 13:44:33 +01:00
std :: pair { "WGPT:PROD" , 18.0e3 },
2023-08-11 15:23:19 +02:00
std :: pair { "WVPT:PROD" , 19.0 },
std :: pair { "WOIT:PROD" , 20.0 },
std :: pair { "WWIT:PROD" , 21.0 },
2023-12-08 13:44:33 +01:00
std :: pair { "WGIT:PROD" , 22.0e3 },
2023-08-11 15:23:19 +02:00
std :: pair { "WVIT:PROD" , 23.0 },
std :: pair { "WOPT:INJ" , 24.0 },
std :: pair { "WWPT:INJ" , 25.0 },
2023-12-08 13:44:33 +01:00
std :: pair { "WGPT:INJ" , 26.0e3 },
2023-08-11 15:23:19 +02:00
std :: pair { "WVPT:INJ" , 27.0 },
std :: pair { "WOIT:INJ" , 28.0 },
std :: pair { "WWIT:INJ" , 29.0 },
2023-12-08 13:44:33 +01:00
std :: pair { "WGIT:INJ" , 30.0e3 },
2023-08-11 15:23:19 +02:00
std :: pair { "WVIT:INJ" , 31.0 },
};
for ( const auto & p : fields ) {
st . set ( p . first , p . second * 1e3 );
}
2024-01-29 16:37:38 +01:00
Opm :: LogOutputHelper < double > helper ( eclState , schedule , st , "dummy version" );
2024-01-04 16:58:43 +01:00
helper . cumulative ( 0 );
2023-08-11 15:23:19 +02:00
std :: string data = trimStream ( str );
BOOST_CHECK_EQUAL ( data , reference );
}
2023-12-15 12:18:34 +01:00
2024-04-11 10:59:32 +02:00
BOOST_FIXTURE_TEST_CASE ( Error , LogWarningFixture )
2023-08-11 15:23:19 +02:00
{
const std :: string reference = R "(Finding the bubble point pressure failed for 3 cells [(2,1,1), (1,3,1), (1,4,1)]
Finding the dew point pressure failed for 3 cells [( 5 , 1 , 1 ), ( 6 , 1 , 1 ), ( 7 , 1 , 1 )]
) ";
Opm :: Parser parser ;
auto python = std :: make_shared < Opm :: Python > ();
auto deck = parser . parseString ( input );
Opm :: EclipseGrid grid ( 10 , 10 , 3 );
Opm :: TableManager table ( deck );
Opm :: FieldPropsManager fp ( deck , Opm :: Phases { true , true , true }, grid , table );
Opm :: Runspec runspec ( deck );
Opm :: Schedule schedule ( deck , grid , fp , runspec , python );
Opm :: EclipseState eclState ( deck );
Opm :: SummaryState st ;
2024-01-29 16:37:38 +01:00
Opm :: LogOutputHelper < double > helper ( eclState , schedule , st , "dummy version" );
2023-08-11 15:23:19 +02:00
2023-11-20 15:06:52 +01:00
str . str ( "" ); // clear out parser errors
2023-08-11 15:23:19 +02:00
helper . error ({ 1 , 20 , 30 }, { 4 , 5 , 6 });
std :: string data = trimStream ( str );
BOOST_CHECK_EQUAL ( data , reference );
}
2024-04-11 10:59:32 +02:00
BOOST_FIXTURE_TEST_CASE ( Fip , LogNoteFixture )
2023-08-11 15:23:19 +02:00
{
2023-12-15 12:18:34 +01:00
const std :: string reference = R "(
==================================================
: FIELD TOTALS :
: PAV = 0 PSIA :
: PORV = 157 RB :
: Pressure is weighted by hydrocarbon pore volume :
: Pore volumes are taken at reference conditions :
:--------------- OIL STB ----------------:-- WAT STB --:--------------- GAS MSCF ----------------:
: LIQUID VAPOUR TOTAL : TOTAL : FREE DISSOLVED TOTAL :
:-------------------------:-------------------------------------------:----------------:-------------------------------------------:
: CURRENTLY IN PLACE : 132 138 120 : 113 : 1 1 1 :
:-------------------------:-------------------------------------------:----------------:-------------------------------------------:
: ORIGINALLY IN PLACE : 25 31 13 : 6 : 0 0 0 :
====================================================================================================================================
==================================================
: FIPNUM REPORT REGION 1 :
: PAV = 0 PSIA :
: PORV = 371 RB :
:--------------- OIL STB ----------------:-- WAT STB --:--------------- GAS MSCF ----------------:
: LIQUID VAPOUR TOTAL : TOTAL : FREE DISSOLVED TOTAL :
:-------------------------:-------------------------------------------:----------------:-------------------------------------------:
: CURRENTLY IN PLACE : 346 352 333 : 327 : 2 2 2 :
:-------------------------:-------------------------------------------:----------------:-------------------------------------------:
: ORIGINALLY IN PLACE : 239 245 226 : 220 : 1 1 1 :
:-------------------------:-------------------------------------------:----------------:-------------------------------------------:
====================================================================================================================================
2023-08-11 15:23:19 +02:00
) ";
Opm :: Parser parser ;
auto python = std :: make_shared < Opm :: Python > ();
auto deck = parser . parseString ( input );
Opm :: EclipseGrid grid ( 10 , 10 , 3 );
Opm :: TableManager table ( deck );
Opm :: FieldPropsManager fp ( deck , Opm :: Phases { true , true , true }, grid , table );
Opm :: Runspec runspec ( deck );
Opm :: Schedule schedule ( deck , grid , fp , runspec , python );
Opm :: EclipseState eclState ( deck );
Opm :: SummaryState st ;
2024-01-29 16:37:38 +01:00
Opm :: LogOutputHelper < double > helper ( eclState , schedule , st , "dummy version" );
2023-08-11 15:23:19 +02:00
Opm :: Inplace initial , current ;
const auto & phases = current . phases ();
2024-01-23 09:42:09 +01:00
int offset = 17 ;
2023-08-11 15:23:19 +02:00
double j = 1.0 ;
for ( const auto & phase : phases ) {
initial . add ( phase , j );
2024-01-23 09:42:09 +01:00
initial . add ( "FIPNUM" , phase , 0 , j + 2 * offset );
initial . add ( "FIPNUM" , phase , 1 , j + 2 * offset );
current . add ( phase , j + offset );
current . add ( "FIPNUM" , phase , 0 , j + 3 * offset );
current . add ( "FIPNUM" , phase , 1 , j + 3 * offset );
2023-08-11 15:23:19 +02:00
++ j ;
}
initial . add ( Opm :: Inplace :: Phase :: PressureHydroCarbonPV , 1.0 );
initial . add ( Opm :: Inplace :: Phase :: HydroCarbonPV , 2.0 );
initial . add ( Opm :: Inplace :: Phase :: PressurePV , 3.0 );
initial . add ( Opm :: Inplace :: Phase :: DynamicPoreVolume , 4.0 );
current . add ( Opm :: Inplace :: Phase :: PressureHydroCarbonPV , 2.0 );
current . add ( Opm :: Inplace :: Phase :: HydroCarbonPV , 4.0 );
current . add ( Opm :: Inplace :: Phase :: PressurePV , 6.0 );
current . add ( Opm :: Inplace :: Phase :: DynamicPoreVolume , 8.0 );
current . add ( "FIPNUM" , Opm :: Inplace :: Phase :: PressureHydroCarbonPV , 1 , 2.0 );
current . add ( "FIPNUM" , Opm :: Inplace :: Phase :: HydroCarbonPV , 1 , 4.0 );
current . add ( "FIPNUM" , Opm :: Inplace :: Phase :: PressurePV , 1 , 6.0 );
current . add ( "FIPNUM" , Opm :: Inplace :: Phase :: DynamicPoreVolume , 1 , 8.0 );
2023-11-08 15:39:41 +01:00
helper . fip ( current , initial , "" );
helper . fip ( current , initial , "FIPNUM" );
2023-12-15 12:18:34 +01:00
BOOST_CHECK_EQUAL ( str . str (), reference );
2023-08-11 15:23:19 +02:00
}
2024-04-11 10:59:32 +02:00
BOOST_FIXTURE_TEST_CASE ( FipResv , LogNoteFixture )
2023-08-11 15:23:19 +02:00
{
2023-12-15 12:18:34 +01:00
const std :: string reference = R "(
===================================
: RESERVOIR VOLUMES RB :
:---------:---------------:---------------:---------------:---------------:---------------:
: REGION : TOTAL PORE : PORE VOLUME : PORE VOLUME : PORE VOLUME : PORE VOLUME :
: : VOLUME : CONTAINING : CONTAINING : CONTAINING : CONTAINING :
: : : OIL : WATER : GAS : HYDRO - CARBON :
:---------:---------------:---------------:---------------:---------------:---------------
: FIELD : 176 : 13 : 19 : 25 : 38 :
: 1 : 176 : 170 : 164 : 176 : 346 :
===========================================================================================
2023-08-11 15:23:19 +02:00
) ";
2023-12-15 12:18:34 +01:00
2023-08-11 15:23:19 +02:00
Opm :: Parser parser ;
auto python = std :: make_shared < Opm :: Python > ();
auto deck = parser . parseString ( input );
Opm :: EclipseGrid grid ( 10 , 10 , 3 );
Opm :: TableManager table ( deck );
Opm :: FieldPropsManager fp ( deck , Opm :: Phases { true , true , true }, grid , table );
Opm :: Runspec runspec ( deck );
Opm :: Schedule schedule ( deck , grid , fp , runspec , python );
Opm :: EclipseState eclState ( deck );
Opm :: SummaryState st ;
2024-01-29 16:37:38 +01:00
Opm :: LogOutputHelper < double > helper ( eclState , schedule , st , "dummy version" );
2023-08-11 15:23:19 +02:00
Opm :: Inplace current ;
const auto & phases = current . phases ();
2024-01-23 09:42:09 +01:00
int offset = 17 ;
2023-08-11 15:23:19 +02:00
double j = 1.0 ;
for ( const auto & phase : phases ) {
2024-01-23 09:42:09 +01:00
current . add ( phase , offset );
current . add ( "FIPNUM" , phase , 1 , j + offset );
2023-08-11 15:23:19 +02:00
++ j ;
}
current . add ( Opm :: Inplace :: Phase :: DynamicPoreVolume , 1.0 );
current . add ( Opm :: Inplace :: Phase :: OilResVolume , 2.0 );
current . add ( Opm :: Inplace :: Phase :: WaterResVolume , 3.0 );
current . add ( Opm :: Inplace :: Phase :: GasResVolume , 4.0 );
2024-01-23 09:42:09 +01:00
current . add ( "FIPNUM" , Opm :: Inplace :: Phase :: DynamicPoreVolume , 1 , 11.0 + offset );
2023-08-11 15:23:19 +02:00
2023-12-15 12:18:34 +01:00
helper . fipResv ( current , "FIPNUM" );
BOOST_CHECK_EQUAL ( str . str (), reference );
2023-08-11 15:23:19 +02:00
}
2023-12-15 12:18:34 +01:00
2024-04-11 10:59:32 +02:00
BOOST_FIXTURE_TEST_CASE ( Injection , LogNoteFixture )
2023-08-11 15:23:19 +02:00
{
const std :: string reference = R "(=================================================== INJECTION REPORT ========================================
: WELL : LOCATION : CTRL : CTRL : CTRL : OIL : WATER : GAS : FLUID : BHP OR : THP OR :
: NAME : ( I , J , K ) : MODE : MODE : MODE : RATE : RATE : RATE : RES . VOL . : CON . PR . : BLK . PR . :
: : : OIL : WAT : GAS : STB / DAY : STB / DAY : MSCF / DAY : RB / DAY : PSIA : PSIA :
2023-12-08 13:44:33 +01:00
=============================================================================================================
2023-08-11 15:23:19 +02:00
: FIELD : : : : : 1.0 : 2.0 : 3.0 : 4.0 : : :
: G1 : : : : : 5.0 : 6.0 : 7.0 : 8.0 : : :
: INJ : 1 , 1 : : : GRAT : 9.0 : 10.0 : 11.0 : 12.0 : 13.0 : 14.0 :
2023-12-07 15:29:08 +01:00
:--------:-----------:------:------:------:-----------:-----------:-----------:-----------:--------:--------:
2023-08-11 15:23:19 +02:00
) ";
Opm :: Parser parser ;
auto python = std :: make_shared < Opm :: Python > ();
auto deck = parser . parseString ( input );
Opm :: EclipseGrid grid ( 10 , 10 , 3 );
Opm :: TableManager table ( deck );
Opm :: FieldPropsManager fp ( deck , Opm :: Phases { true , true , true }, grid , table );
Opm :: Runspec runspec ( deck );
Opm :: Schedule schedule ( deck , grid , fp , runspec , python );
Opm :: EclipseState eclState ( deck );
Opm :: SummaryState st ;
constexpr auto fields = std :: array {
std :: pair { "FOIR" , 1.0 },
std :: pair { "FWIR" , 2.0 },
std :: pair { "FGIR" , 3.0 },
std :: pair { "FVIR" , 4.0 },
std :: pair { "GOIR:G1" , 5.0 },
std :: pair { "GWIR:G1" , 6.0 },
std :: pair { "GGIR:G1" , 7.0 },
std :: pair { "GVIR:G1" , 8.0 },
std :: pair { "WOIR:INJ" , 9.0 },
std :: pair { "WWIR:INJ" , 10.0 },
std :: pair { "WGIR:INJ" , 11.0 },
std :: pair { "WVIR:INJ" , 12.0 },
std :: pair { "WBHP:INJ" , 13.0 },
std :: pair { "WTHP:INJ" , 14.0 },
};
for ( const auto & p : fields ) {
st . set ( p . first , p . second );
}
2024-01-29 16:37:38 +01:00
Opm :: LogOutputHelper < double > helper ( eclState , schedule , st , "dummy version" );
2024-01-04 16:58:43 +01:00
helper . injection ( 0 );
2023-08-11 15:23:19 +02:00
std :: string data = trimStream ( str );
BOOST_CHECK_EQUAL ( data , reference );
}
2023-12-15 12:18:34 +01:00
2024-04-11 10:59:32 +02:00
BOOST_FIXTURE_TEST_CASE ( Production , LogNoteFixture )
2023-08-11 15:23:19 +02:00
{
const std :: string reference = R "(======================================================= PRODUCTION REPORT =======================================================
: WELL : LOCATION : CTRL : OIL : WATER : GAS : FLUID : WATER : GAS / OIL : WAT / GAS : BHP OR : THP OR :
: NAME : ( I , J , K ) : MODE : RATE : RATE : RATE : RES . VOL . : CUT : RATIO : RATIO : CON . PR . : BLK . PR . :
: : : : STB / DAY : STB / DAY : MSCF / DAY : RB / DAY : : MSCF / STB : STB / MSCF : PSIA : PSIA :
=================================================================================================================================
: FIELD : : : 1.0 : 2.0 : 3.0 : 4.0 : 5.000 : 6.00 : 0.6667 : : :
: G1 : : : 7.0 : 8.0 : 9.0 : 10.0 : 11.000 : 12.00 : 0.8889 : : :
: PROD : 10 , 10 : ORAT : 13.0 : 14.0 : 15.0 : 16.0 : 17.000 : 18.00 : 0.9333 : 19.0 : 20.0 :
:--------:-----------:----:-----------:-----------:-----------:-----------:-----------:----------:------------:--------:--------:
) ";
2023-11-20 15:06:52 +01:00
2023-08-11 15:23:19 +02:00
Opm :: Parser parser ;
auto python = std :: make_shared < Opm :: Python > ();
auto deck = parser . parseString ( input );
Opm :: EclipseGrid grid ( 10 , 10 , 3 );
Opm :: TableManager table ( deck );
Opm :: FieldPropsManager fp ( deck , Opm :: Phases { true , true , true }, grid , table );
Opm :: Runspec runspec ( deck );
Opm :: Schedule schedule ( deck , grid , fp , runspec , python );
Opm :: EclipseState eclState ( deck );
Opm :: SummaryState st ;
constexpr auto fields = std :: array {
std :: pair { "FOPR" , 1.0 },
std :: pair { "FWPR" , 2.0 },
std :: pair { "FGPR" , 3.0 },
std :: pair { "FVPR" , 4.0 },
std :: pair { "FWCT" , 5.0 },
std :: pair { "FGOR" , 6.0 },
std :: pair { "GOPR:G1" , 7.0 },
std :: pair { "GWPR:G1" , 8.0 },
std :: pair { "GGPR:G1" , 9.0 },
std :: pair { "GVPR:G1" , 10.0 },
std :: pair { "GWCT:G1" , 11.0 },
std :: pair { "GGOR:G1" , 12.0 },
std :: pair { "WOPR:PROD" , 13.0 },
std :: pair { "WWPR:PROD" , 14.0 },
std :: pair { "WGPR:PROD" , 15.0 },
std :: pair { "WVPR:PROD" , 16.0 },
std :: pair { "WWCT:PROD" , 17.0 },
std :: pair { "WGOR:PROD" , 18.0 },
std :: pair { "WBHP:PROD" , 19.0 },
std :: pair { "WTHP:PROD" , 20.0 },
};
for ( const auto & p : fields ) {
st . set ( p . first , p . second );
}
2024-01-29 16:37:38 +01:00
Opm :: LogOutputHelper < double > helper ( eclState , schedule , st , "dummy version" );
2024-01-04 16:58:43 +01:00
helper . production ( 0 );
2023-08-11 15:23:19 +02:00
std :: string data = trimStream ( str );
BOOST_CHECK_EQUAL ( data , reference );
}
2023-12-15 12:18:34 +01:00