2018-03-23 06:41:26 -05:00
/*
2023-01-11 04:23:40 -06:00
Copyright 2018 Statoil ASA .
2018-03-23 06:41:26 -05:00
This file is part of the Open Porous Media project ( OPM ) .
2023-01-11 04:23:40 -06:00
2018-03-23 06:41:26 -05:00
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 .
2023-01-11 04:23:40 -06:00
2018-03-23 06:41:26 -05:00
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 .
2023-01-11 04:23:40 -06:00
2018-03-23 06:41:26 -05:00
You should have received a copy of the GNU General Public License
along with OPM . If not , see < http : //www.gnu.org/licenses/>.
*/
# define BOOST_TEST_MODULE UDQTests
2021-05-25 15:23:41 -05:00
2018-03-23 06:41:26 -05:00
# include <boost/test/unit_test.hpp>
2021-05-25 15:23:41 -05:00
2020-09-25 01:46:27 -05:00
# include <opm/common/utility/OpmInputError.hpp>
2022-03-11 02:43:35 -06:00
# include <opm/common/utility/TimeService.hpp>
2022-07-26 08:00:59 -05:00
# include <opm/input/eclipse/EclipseState/EclipseState.hpp>
2022-03-11 02:43:35 -06:00
# include <opm/input/eclipse/EclipseState/Grid/FieldPropsManager.hpp>
2021-12-14 01:06:42 -06:00
# include <opm/input/eclipse/EclipseState/Runspec.hpp>
2022-03-11 02:43:35 -06:00
# include <opm/input/eclipse/Python/Python.hpp>
2023-01-19 06:20:52 -06:00
# include <opm/input/eclipse/Schedule/MSW/SegmentMatcher.hpp>
# include <opm/input/eclipse/Schedule/MSW/WellSegments.hpp>
2021-12-14 01:13:41 -06:00
# include <opm/input/eclipse/Schedule/Schedule.hpp>
2023-01-19 06:20:52 -06:00
# include <opm/input/eclipse/Schedule/ScheduleState.hpp>
2022-03-11 02:43:35 -06:00
# include <opm/input/eclipse/Schedule/SummaryState.hpp>
# include <opm/input/eclipse/Schedule/UDQ/UDQActive.hpp>
# include <opm/input/eclipse/Schedule/UDQ/UDQAssign.hpp>
2021-12-14 01:13:41 -06:00
# include <opm/input/eclipse/Schedule/UDQ/UDQConfig.hpp>
# include <opm/input/eclipse/Schedule/UDQ/UDQContext.hpp>
2022-03-11 02:43:35 -06:00
# include <opm/input/eclipse/Schedule/UDQ/UDQEnums.hpp>
2021-12-14 01:13:41 -06:00
# include <opm/input/eclipse/Schedule/UDQ/UDQFunction.hpp>
# include <opm/input/eclipse/Schedule/UDQ/UDQFunctionTable.hpp>
2022-03-11 02:43:35 -06:00
# include <opm/input/eclipse/Schedule/UDQ/UDQSet.hpp>
2021-12-14 01:13:41 -06:00
# include <opm/input/eclipse/Schedule/UDQ/UDQState.hpp>
# include <opm/input/eclipse/Schedule/Well/NameOrder.hpp>
2023-01-19 06:20:52 -06:00
# include <opm/input/eclipse/Schedule/Well/Well.hpp>
2022-03-11 02:43:35 -06:00
# include <opm/input/eclipse/Schedule/Well/WellMatcher.hpp>
2018-03-23 06:41:26 -05:00
2022-03-11 02:43:35 -06:00
# include <opm/input/eclipse/Utility/Typetools.hpp>
2018-03-23 06:41:26 -05:00
2022-03-11 02:43:35 -06:00
# include <opm/input/eclipse/Parser/ErrorGuard.hpp>
2023-01-11 06:35:42 -06:00
# include <opm/input/eclipse/Parser/InputErrorAction.hpp>
2022-03-11 02:43:35 -06:00
# include <opm/input/eclipse/Parser/ParseContext.hpp>
# include <opm/input/eclipse/Parser/Parser.hpp>
2020-06-29 13:56:16 -05:00
2022-03-11 02:43:35 -06:00
# include <opm/input/eclipse/Deck/Deck.hpp>
# include <opm/input/eclipse/Deck/UDAValue.hpp>
2023-01-19 06:20:52 -06:00
# include <algorithm>
2022-03-11 02:43:35 -06:00
# include <cmath>
# include <cstddef>
# include <memory>
# include <limits>
# include <stdexcept>
# include <string>
2023-01-19 06:20:52 -06:00
# include <utility>
2022-03-11 02:43:35 -06:00
# include <vector>
using namespace Opm ;
namespace {
2023-01-19 06:20:52 -06:00
Schedule make_schedule ( const std : : string & input )
{
auto deck = Parser { } . parseString ( input ) ;
2022-03-11 02:43:35 -06:00
if ( deck . hasKeyword ( " DIMENS " ) ) {
EclipseState es ( deck ) ;
2023-01-19 06:20:52 -06:00
return { deck , es , std : : make_shared < Python > ( ) } ;
}
else {
2022-03-11 02:43:35 -06:00
EclipseGrid grid ( 10 , 10 , 10 ) ;
2023-01-19 06:20:52 -06:00
TableManager table ( deck ) ;
FieldPropsManager fp ( deck , Phases { true , true , true } , grid , table ) ;
Runspec runspec ( deck ) ;
return { deck , grid , fp , runspec , std : : make_shared < Python > ( ) } ;
}
}
Opm : : Segment makeSegment ( const int segmentNumber )
{
return { segmentNumber , 1 , 1 , 1.0 , 0.0 , 0.5 , 0.01 , 0.25 , 1.23 , true , 0.0 , 0.0 } ;
}
std : : shared_ptr < Opm : : WellSegments > makeSegments ( const int numSegments )
{
auto segments = std : : vector < Opm : : Segment > { } ;
segments . reserve ( numSegments ) ;
for ( auto segment = 0 ; segment < numSegments ; + + segment ) {
segments . push_back ( makeSegment ( segment + 1 ) ) ;
}
return std : : make_shared < Opm : : WellSegments >
( Opm : : WellSegments : : CompPressureDrop : : HFA , segments ) ;
}
Opm : : Well makeProducerWell ( const std : : string & wname ,
const std : : size_t insert ,
const int numSegments )
{
auto w = Opm : : Well {
wname , " G " , 0 , insert , 1 , 2 , { } ,
Opm : : WellType { true , Opm : : Phase : : OIL } , // Oil producer
Opm : : Well : : ProducerCMode : : ORAT ,
Opm : : Connection : : Order : : INPUT ,
Opm : : UnitSystem : : newMETRIC ( ) ,
- 3.0e+20 , // UDQ undefined
0.0 , true , true , 0 ,
Opm : : Well : : GasInflowEquation : : STD
} ;
if ( numSegments > 0 ) {
w . updateSegments ( makeSegments ( numSegments ) ) ;
}
return w ;
}
Opm : : Well makeInjectionWell ( const std : : string & wname ,
const std : : size_t insert ,
const int numSegments )
{
auto w = Opm : : Well {
wname , " G " , 0 , insert , 1 , 2 , { } ,
Opm : : WellType { false , Opm : : Phase : : GAS } , // Gas injector
Opm : : Well : : ProducerCMode : : ORAT ,
Opm : : Connection : : Order : : INPUT ,
Opm : : UnitSystem : : newMETRIC ( ) ,
- 3.0e+20 , // UDQ undefined
0.0 , true , true , 0 ,
Opm : : Well : : GasInflowEquation : : STD
} ;
if ( numSegments > 0 ) {
w . updateSegments ( makeSegments ( numSegments ) ) ;
2022-03-11 02:43:35 -06:00
}
2023-01-19 06:20:52 -06:00
return w ;
2020-06-29 13:56:16 -05:00
}
2023-01-19 06:20:52 -06:00
// Collection of wells
// OP-01: Producer, MSW, 20 segments (1 .. 20)
// OP-02: Producer, MSW, 5 segments (1 .. 5)
// OP-06: Producer, Standard well
// OPROD: Producer, MSW, 2 segments (1 .. 2)
//
// GI-01: Injector, MSW, 10 segments (1 .. 10)
// GI-08: Injector, Standard well
// I-45: Injector, MSW, 1 segment (1)
Opm : : ScheduleState dynamicInputData ( )
{
auto block = Opm : : ScheduleState { Opm : : TimeService : : now ( ) } ;
block . wells . update ( makeProducerWell ( " OP-01 " , 0 , 20 ) ) ;
block . wells . update ( makeProducerWell ( " OP-02 " , 1 , 5 ) ) ;
block . wells . update ( makeProducerWell ( " OP-06 " , 2 , 0 ) ) ;
block . wells . update ( makeProducerWell ( " OPROD " , 3 , 2 ) ) ;
block . wells . update ( makeInjectionWell ( " GI-01 " , 4 , 10 ) ) ;
block . wells . update ( makeInjectionWell ( " GI-08 " , 5 , 0 ) ) ;
block . wells . update ( makeInjectionWell ( " I-45 " , 6 , 1 ) ) ;
block . well_order . update ( Opm : : NameOrder {
" OP-01 " , " OP-02 " , " OP-06 " , " OPROD " , " GI-01 " , " GI-08 " , " I-45 " ,
} ) ;
return block ;
}
} // Anonymous namespace
2020-06-29 13:56:16 -05:00
2019-12-17 09:45:53 -06:00
BOOST_AUTO_TEST_CASE ( TYPE_COERCION ) {
BOOST_CHECK ( UDQVarType : : SCALAR = = UDQ : : coerce ( UDQVarType : : SCALAR , UDQVarType : : SCALAR ) ) ;
BOOST_CHECK ( UDQVarType : : WELL_VAR = = UDQ : : coerce ( UDQVarType : : SCALAR , UDQVarType : : WELL_VAR ) ) ;
BOOST_CHECK ( UDQVarType : : WELL_VAR = = UDQ : : coerce ( UDQVarType : : WELL_VAR , UDQVarType : : FIELD_VAR ) ) ;
BOOST_CHECK ( UDQVarType : : GROUP_VAR = = UDQ : : coerce ( UDQVarType : : SCALAR , UDQVarType : : GROUP_VAR ) ) ;
BOOST_CHECK ( UDQVarType : : GROUP_VAR = = UDQ : : coerce ( UDQVarType : : GROUP_VAR , UDQVarType : : FIELD_VAR ) ) ;
BOOST_CHECK_THROW ( UDQ : : coerce ( UDQVarType : : GROUP_VAR , UDQVarType : : WELL_VAR ) , std : : logic_error ) ;
BOOST_CHECK_THROW ( UDQ : : coerce ( UDQVarType : : WELL_VAR , UDQVarType : : GROUP_VAR ) , std : : logic_error ) ;
}
BOOST_AUTO_TEST_CASE ( GROUP_VARIABLES )
{
2020-09-27 15:13:30 -05:00
KeywordLocation location ;
2019-12-17 09:45:53 -06:00
UDQParams udqp ;
UDQFunctionTable udqft ;
2020-11-15 03:03:34 -06:00
UDQDefine def_group ( udqp , " GUOPRL " , 0 , location , { " ( " , " 5000 " , " - " , " GOPR " , " LOWER " , " * " , " 0.13 " , " - " , " GOPR " , " UPPER " , " * " , " 0.15 " , " ) " , " * " , " 0.89 " }) ;
2021-02-28 10:04:35 -06:00
SummaryState st ( TimeService : : now ( ) ) ;
2020-08-31 00:38:52 -05:00
UDQState udq_state ( udqp . undefinedValue ( ) ) ;
2023-01-19 06:20:52 -06:00
auto segmentMatcherFactory = [ ] ( ) { return std : : make_unique < SegmentMatcher > ( ScheduleState { } ) ; } ;
2023-10-23 08:07:23 -05:00
UDQContext context ( udqft , { } , { } , segmentMatcherFactory , st , udq_state ) ;
2019-12-17 09:45:53 -06:00
double gopr_lower = 1234 ;
double gopr_upper = 4321 ;
st . update_group_var ( " LOWER " , " GOPR " , gopr_lower ) ;
st . update_group_var ( " UPPER " , " GOPR " , gopr_upper ) ;
auto res_group = def_group . eval ( context ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( res_group [ " UPPER " ] . get ( ) , ( 5000 - gopr_lower * 0.13 - gopr_upper * 0.15 ) * 0.89 ) ;
BOOST_CHECK_EQUAL ( res_group [ " UPPER " ] . get ( ) , ( 5000 - gopr_lower * 0.13 - gopr_upper * 0.15 ) * 0.89 ) ;
2020-10-15 04:39:07 -05:00
BOOST_CHECK_THROW ( context . get_group_var ( " LOWER " , " GGPR " ) , std : : exception ) ;
auto empty_value = context . get_group_var ( " NO_SUCH_GROUP " , " GOPR " ) ;
BOOST_CHECK ( ! empty_value ) ;
2019-12-17 09:45:53 -06:00
}
2023-01-19 06:20:52 -06:00
BOOST_AUTO_TEST_CASE ( SINGLE_SEGMENT_VARIABLES )
{
const auto location = KeywordLocation { } ;
const auto udqp = UDQParams { } ;
const auto udqft = UDQFunctionTable { } ;
const auto def_seg = UDQDefine {
udqp , " SU_OFR " , 0 , location ,
{ " ( " , " 5000 " , " - " , " SOFR " , " 'OP-*' " , " 3 " , " * " , " 0.13 " , " ) " , " * " , " 0.89 " }
} ;
auto st = SummaryState { TimeService : : now ( ) } ;
auto udq_state = UDQState { udqp . undefinedValue ( ) } ;
auto segmentMatcherFactory = [ sched_state = dynamicInputData ( ) ] ( )
{
return std : : make_unique < SegmentMatcher > ( sched_state ) ;
} ;
auto context = UDQContext {
2023-10-23 08:07:23 -05:00
udqft , { } , { } , segmentMatcherFactory , st , udq_state
2023-01-19 06:20:52 -06:00
} ;
const auto sofr_p1_3 = 1234.0 ;
const auto sofr_p2_3 = 4321.0 ;
2019-12-17 09:45:53 -06:00
2023-01-19 06:20:52 -06:00
st . update_segment_var ( " OP-01 " , " SOFR " , 3 , sofr_p1_3 ) ;
st . update_segment_var ( " OP-02 " , " SOFR " , 3 , sofr_p2_3 ) ;
const auto res_seg = def_seg . eval ( context ) ;
BOOST_CHECK_EQUAL ( res_seg ( " OP-01 " , 3 ) . get ( ) , ( 5000.0 - sofr_p1_3 * 0.13 ) * 0.89 ) ;
BOOST_CHECK_EQUAL ( res_seg ( " OP-02 " , 3 ) . get ( ) , ( 5000.0 - sofr_p2_3 * 0.13 ) * 0.89 ) ;
}
2019-12-17 09:45:53 -06:00
BOOST_AUTO_TEST_CASE ( SUBTRACT )
{
2020-09-27 15:13:30 -05:00
KeywordLocation location ;
2019-12-17 09:45:53 -06:00
UDQParams udqp ;
UDQFunctionTable udqft ;
2020-11-15 03:03:34 -06:00
UDQDefine def ( udqp , " WU " , 0 , location , { " 16 " , " - " , " 8 " , " - " , " 4 " , " - " , " 2 " , " - " , " 1 " } ) ;
UDQDefine scalar ( udqp , " WU " , 0 , location , { " 16 " } ) ;
2019-12-17 09:45:53 -06:00
2021-02-28 10:04:35 -06:00
SummaryState st ( TimeService : : now ( ) ) ;
2020-08-31 00:38:52 -05:00
UDQState udq_state ( udqp . undefinedValue ( ) ) ;
2023-01-10 03:44:15 -06:00
WellMatcher wm ( NameOrder ( { " P1 " } ) ) ;
2023-01-19 06:20:52 -06:00
auto segmentMatcherFactory = [ ] ( ) { return std : : make_unique < SegmentMatcher > ( ScheduleState { } ) ; } ;
2023-10-23 08:07:23 -05:00
UDQContext context ( udqft , wm , { } , segmentMatcherFactory , st , udq_state ) ;
2019-12-17 09:45:53 -06:00
st . update_well_var ( " P1 " , " WOPR " , 4 ) ;
auto res = def . eval ( context ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( res [ 0 ] . get ( ) , 1.0 ) ;
2019-12-17 09:45:53 -06:00
auto res2 = scalar . eval ( context ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( res2 [ 0 ] . get ( ) , 16.0 ) ;
2019-12-17 09:45:53 -06:00
}
2019-12-13 08:59:04 -06:00
BOOST_AUTO_TEST_CASE ( TEST )
{
2020-09-27 15:13:30 -05:00
KeywordLocation location ;
2019-12-13 08:59:04 -06:00
UDQParams udqp ;
UDQFunctionTable udqft ;
2020-11-15 03:03:34 -06:00
UDQDefine def1 ( udqp , " WUWI3 " , 0 , location , { " GOPR " , " MAU " , " * " , " 2.0 " , " * " , " 0.25 " , " * " , " 10 " } ) ;
UDQDefine def2 ( udqp , " WUWI3 " , 0 , location , { " 2.0 " , " * " , " 0.25 " , " * " , " 3 " } ) ;
UDQDefine def3 ( udqp , " WUWI3 " , 0 , location , { " GOPR " , " FIELD " , " - " , " 2.0 " , " * " , " 3 " } ) ;
UDQDefine def4 ( udqp , " WUWI3 " , 0 , location , { " FOPR " , " / " , " 2 " } ) ;
2019-12-13 08:59:04 -06:00
2021-02-28 10:04:35 -06:00
SummaryState st ( TimeService : : now ( ) ) ;
2020-08-31 00:38:52 -05:00
UDQState udq_state ( udqp . undefinedValue ( ) ) ;
2023-01-10 03:44:15 -06:00
WellMatcher wm ( NameOrder ( { " P1 " , " P2 " } ) ) ;
2023-01-19 06:20:52 -06:00
auto segmentMatcherFactory = [ ] ( ) { return std : : make_unique < SegmentMatcher > ( ScheduleState { } ) ; } ;
2023-10-23 08:07:23 -05:00
UDQContext context ( udqft , wm , { } , segmentMatcherFactory , st , udq_state ) ;
2019-12-13 08:59:04 -06:00
st . update_group_var ( " MAU " , " GOPR " , 4 ) ;
st . update_group_var ( " XXX " , " GOPR " , 5 ) ;
st . update_group_var ( " FIELD " , " GOPR " , 6 ) ;
st . update_well_var ( " P1 " , " WBHP " , 0.5 ) ;
st . update_well_var ( " P2 " , " WBHP " , 0.5 ) ;
st . update ( " FOPR " , 2 ) ;
auto res1 = def1 . eval ( context ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( res1 [ " P1 " ] . get ( ) , 20 ) ;
BOOST_CHECK_EQUAL ( res1 [ " P2 " ] . get ( ) , 20 ) ;
2019-12-13 08:59:04 -06:00
auto res2 = def2 . eval ( context ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( res2 [ " P1 " ] . get ( ) , 1.50 ) ;
BOOST_CHECK_EQUAL ( res2 [ " P2 " ] . get ( ) , 1.50 ) ;
2019-12-13 08:59:04 -06:00
auto res3 = def3 . eval ( context ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( res3 [ " P1 " ] . get ( ) , 0.00 ) ;
BOOST_CHECK_EQUAL ( res3 [ " P2 " ] . get ( ) , 0.00 ) ;
2019-12-13 08:59:04 -06:00
auto res4 = def4 . eval ( context ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( res4 [ " P1 " ] . get ( ) , 1.00 ) ;
BOOST_CHECK_EQUAL ( res4 [ " P2 " ] . get ( ) , 1.00 ) ;
2019-12-13 08:59:04 -06:00
2023-01-11 04:21:32 -06:00
// This expression has a well set as target type, and involves group
// with wildcard that is not supported by flow.
BOOST_CHECK_THROW ( UDQDefine ( udqp , " GUPR2 " , 0 , location , { " GOPR " , " G* " , " * " , " 2.0 " } ) , OpmInputError ) ;
// UDQVarType == BLOCK is not yet supported.
BOOST_CHECK_THROW ( UDQDefine ( udqp , " BUPR2 " , 0 , location , { " BPR " , " 1 " , " 1 " , " 1 " , " * " , " 2.0 " } ) , std : : invalid_argument ) ;
2019-12-13 08:59:04 -06:00
}
2019-01-28 09:52:28 -06:00
2019-03-07 03:54:56 -06:00
BOOST_AUTO_TEST_CASE ( MIX_SCALAR ) {
UDQFunctionTable udqft ;
2019-03-11 05:43:23 -05:00
UDQParams udqp ;
2020-09-27 15:13:30 -05:00
KeywordLocation location ;
2020-11-15 03:03:34 -06:00
UDQDefine def_add ( udqp , " WU " , 0 , location , { " WOPR " , " + " , " 1 " } ) ;
2021-02-28 10:04:35 -06:00
SummaryState st ( TimeService : : now ( ) ) ;
2020-08-31 00:38:52 -05:00
UDQState udq_state ( udqp . undefinedValue ( ) ) ;
2023-01-10 03:44:15 -06:00
WellMatcher wm ( NameOrder ( { " P1 " } ) ) ;
2023-01-19 06:20:52 -06:00
auto segmentMatcherFactory = [ ] ( ) { return std : : make_unique < SegmentMatcher > ( ScheduleState { } ) ; } ;
2023-10-23 08:07:23 -05:00
UDQContext context ( udqft , wm , { } , segmentMatcherFactory , st , udq_state ) ;
2019-03-07 03:54:56 -06:00
2019-05-12 03:01:26 -05:00
st . update_well_var ( " P1 " , " WOPR " , 1 ) ;
2019-03-07 03:54:56 -06:00
2019-05-24 08:50:40 -05:00
auto res_add = def_add . eval ( context ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( res_add [ " P1 " ] . get ( ) , 2 ) ;
2019-03-07 03:54:56 -06:00
}
2019-05-24 08:50:40 -05:00
BOOST_AUTO_TEST_CASE ( UDQFieldSetTest ) {
std : : vector < std : : string > wells = { " P1 " , " P2 " , " P3 " , " P4 " } ;
2020-09-27 15:13:30 -05:00
KeywordLocation location ;
2019-05-24 08:50:40 -05:00
UDQParams udqp ;
UDQFunctionTable udqft ( udqp ) ;
2021-02-28 10:04:35 -06:00
SummaryState st ( TimeService : : now ( ) ) ;
2020-08-31 00:38:52 -05:00
UDQState udq_state ( udqp . undefinedValue ( ) ) ;
2023-01-10 03:44:15 -06:00
WellMatcher wm ( NameOrder ( { " P1 " , " P2 " , " P3 " , " P4 " } ) ) ;
2023-01-19 06:20:52 -06:00
auto segmentMatcherFactory = [ ] ( ) { return std : : make_unique < SegmentMatcher > ( ScheduleState { } ) ; } ;
2023-10-23 08:07:23 -05:00
UDQContext context ( udqft , wm , { } , segmentMatcherFactory , st , udq_state ) ;
2019-05-24 08:50:40 -05:00
st . update_well_var ( " P1 " , " WOPR " , 1.0 ) ;
st . update_well_var ( " P2 " , " WOPR " , 2.0 ) ;
st . update_well_var ( " P3 " , " WOPR " , 3.0 ) ;
st . update_well_var ( " P4 " , " WOPR " , 4.0 ) ;
2023-01-11 04:23:40 -06:00
#if 0
{
2019-12-17 09:45:53 -06:00
UDQDefine def_fxxx ( udqp , " FU_SCALAR " , { " 123 " } ) ;
auto fxxx_res = def_fxxx . eval ( context ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( fxxx_res [ 0 ] . get ( ) , 123.0 ) ;
2019-12-17 09:45:53 -06:00
BOOST_CHECK ( fxxx_res . var_type ( ) = = UDQVarType : : FIELD_VAR ) ;
}
2023-01-11 04:23:40 -06:00
# endif
2019-05-24 08:50:40 -05:00
2019-12-17 09:45:53 -06:00
{
2020-11-15 03:03:34 -06:00
UDQDefine def_fopr ( udqp , " FUOPR " , 0 , location , { " SUM " , " ( " , " WOPR " , " ) " }) ;
2019-12-17 09:45:53 -06:00
auto fopr_res = def_fopr . eval ( context ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( fopr_res [ 0 ] . get ( ) , 10.0 ) ;
2019-12-17 09:45:53 -06:00
}
2019-05-24 08:50:40 -05:00
}
2020-06-11 08:19:47 -05:00
BOOST_AUTO_TEST_CASE ( UDQWellSetNANTest ) {
std : : vector < std : : string > wells = { " P1 " , " P2 " , " I1 " , " I2 " } ;
UDQSet ws = UDQSet : : wells ( " NAME " , wells ) ;
2020-08-31 01:45:30 -05:00
UDQSet ws2 = UDQSet : : wells ( " NAME " , wells ) ;
BOOST_CHECK ( ws = = ws2 ) ;
2020-06-11 08:19:47 -05:00
for ( std : : size_t i = 0 ; i < 4 ; i + + )
ws . assign ( i , i * 1.0 ) ;
2020-09-29 06:54:21 -05:00
BOOST_CHECK_EQUAL ( ws . defined_size ( ) , 4U ) ;
2020-06-11 08:19:47 -05:00
ws . assign ( 1 , std : : numeric_limits < double > : : quiet_NaN ( ) ) ;
ws . assign ( 3 , std : : numeric_limits < double > : : quiet_NaN ( ) ) ;
2020-09-29 06:54:21 -05:00
BOOST_CHECK_EQUAL ( ws . defined_size ( ) , 2U ) ;
2020-08-27 10:25:38 -05:00
BOOST_CHECK ( ws . has ( " P1 " ) ) ;
BOOST_CHECK ( ws . has ( " P2 " ) ) ;
2020-06-11 08:19:47 -05:00
}
2019-03-07 03:44:31 -06:00
BOOST_AUTO_TEST_CASE ( UDQWellSetTest ) {
std : : vector < std : : string > wells = { " P1 " , " P2 " , " I1 " , " I2 " } ;
2019-05-24 08:50:40 -05:00
UDQSet ws = UDQSet : : wells ( " NAME " , wells ) ;
UDQSet ws2 = UDQSet : : wells ( " NAME " , wells , 100.0 ) ;
2019-03-07 03:44:31 -06:00
2020-09-29 06:54:21 -05:00
BOOST_CHECK_EQUAL ( 4U , ws . size ( ) ) ;
2019-03-07 03:44:31 -06:00
ws . assign ( " P1 " , 1.0 ) ;
const auto & value = ws [ " P1 " ] ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( value . get ( ) , 1.0 ) ;
BOOST_CHECK_EQUAL ( ws [ " P1 " ] . get ( ) , 1.0 ) ;
2019-03-07 03:44:31 -06:00
2019-05-24 08:50:40 -05:00
BOOST_REQUIRE_THROW ( ws . assign ( " NO_SUCH_WELL " , 1.0 ) , std : : out_of_range ) ;
2019-12-13 08:38:55 -06:00
BOOST_REQUIRE_THROW ( ws [ 10 ] , std : : out_of_range ) ;
BOOST_REQUIRE_THROW ( ws [ " NO_SUCH_WELL " ] , std : : out_of_range ) ;
2019-03-07 03:44:31 -06:00
ws . assign ( " * " , 2.0 ) ;
for ( const auto & w : wells )
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( ws [ w ] . get ( ) , 2.0 ) ;
2019-03-07 03:44:31 -06:00
ws . assign ( 3.0 ) ;
for ( const auto & w : wells )
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( ws [ w ] . get ( ) , 3.0 ) ;
2019-03-07 03:44:31 -06:00
ws . assign ( " P* " , 4.0 ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( ws [ " P1 " ] . get ( ) , 4.0 ) ;
BOOST_CHECK_EQUAL ( ws [ " P2 " ] . get ( ) , 4.0 ) ;
2019-03-07 03:44:31 -06:00
ws . assign ( " I2 " , 5.0 ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( ws [ " I2 " ] . get ( ) , 5.0 ) ;
2019-03-07 03:44:31 -06:00
for ( const auto & w : wells )
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( ws2 [ w ] . get ( ) , 100.0 ) ;
2019-03-07 03:44:31 -06:00
2019-05-24 08:50:40 -05:00
UDQSet scalar = UDQSet : : scalar ( " NAME " , 1.0 ) ;
2020-09-29 06:54:21 -05:00
BOOST_CHECK_EQUAL ( scalar . size ( ) , 1U ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( scalar [ 0 ] . get ( ) , 1.0 ) ;
2019-03-07 03:44:31 -06:00
2019-05-24 08:50:40 -05:00
UDQSet empty = UDQSet : : empty ( " EMPTY " ) ;
2020-09-29 06:54:21 -05:00
BOOST_CHECK_EQUAL ( empty . size ( ) , 0U ) ;
2019-03-07 03:44:31 -06:00
}
2019-01-28 09:52:28 -06:00
2019-05-24 08:50:40 -05:00
BOOST_AUTO_TEST_CASE ( UDQ_GROUP_TEST ) {
std : : vector < std : : string > groups = { " G1 " , " G2 " , " G3 " , " G4 " } ;
UDQSet gs = UDQSet : : groups ( " NAME " , groups ) ;
2020-09-29 06:54:21 -05:00
BOOST_CHECK_EQUAL ( 4U , gs . size ( ) ) ;
2019-05-24 08:50:40 -05:00
gs . assign ( " G1 " , 1.0 ) ;
const auto & value = gs [ " G1 " ] ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( value . get ( ) , 1.0 ) ;
2019-05-24 08:50:40 -05:00
{
2020-09-27 15:13:30 -05:00
KeywordLocation location ;
2019-05-24 08:50:40 -05:00
UDQParams udqp ;
UDQFunctionTable udqft ( udqp ) ;
2020-11-15 03:03:34 -06:00
UDQDefine def_fopr ( udqp , " FUOPR " , 0 , location , { " SUM " , " ( " , " GOPR " , " ) " }) ;
2021-02-28 10:04:35 -06:00
SummaryState st ( TimeService : : now ( ) ) ;
2020-08-31 00:38:52 -05:00
UDQState udq_state ( udqp . undefinedValue ( ) ) ;
2023-01-19 06:20:52 -06:00
auto segmentMatcherFactory = [ ] ( ) { return std : : make_unique < SegmentMatcher > ( ScheduleState { } ) ; } ;
2023-10-23 08:07:23 -05:00
UDQContext context ( udqft , { } , { } , segmentMatcherFactory , st , udq_state ) ;
2019-05-24 08:50:40 -05:00
st . update_group_var ( " G1 " , " GOPR " , 1.0 ) ;
st . update_group_var ( " G2 " , " GOPR " , 2.0 ) ;
st . update_group_var ( " G3 " , " GOPR " , 3.0 ) ;
st . update_group_var ( " G4 " , " GOPR " , 4.0 ) ;
auto res = def_fopr . eval ( context ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( res [ 0 ] . get ( ) , 10.0 ) ;
2019-05-24 08:50:40 -05:00
}
}
2019-03-07 03:54:56 -06:00
BOOST_AUTO_TEST_CASE ( UDQ_DEFINETEST ) {
2019-03-11 05:43:23 -05:00
UDQParams udqp ;
UDQFunctionTable udqft ( udqp ) ;
2020-09-27 15:13:30 -05:00
KeywordLocation location ;
2019-03-07 03:54:56 -06:00
{
2020-11-15 03:03:34 -06:00
UDQDefine def ( udqp , " WUBHP " , 0 , location , { " WBHP " } ) ;
2021-02-28 10:04:35 -06:00
SummaryState st ( TimeService : : now ( ) ) ;
2020-08-31 00:38:52 -05:00
UDQState udq_state ( udqp . undefinedValue ( ) ) ;
2023-01-10 03:44:15 -06:00
WellMatcher wm ( NameOrder ( { " W1 " , " W2 " , " W3 " } ) ) ;
2023-01-19 06:20:52 -06:00
auto segmentMatcherFactory = [ ] ( ) { return std : : make_unique < SegmentMatcher > ( ScheduleState { } ) ; } ;
2023-10-23 08:07:23 -05:00
UDQContext context ( udqft , wm , { } , segmentMatcherFactory , st , udq_state ) ;
2019-03-07 03:54:56 -06:00
2019-05-12 03:01:26 -05:00
st . update_well_var ( " W1 " , " WBHP " , 11 ) ;
st . update_well_var ( " W2 " , " WBHP " , 2 ) ;
st . update_well_var ( " W3 " , " WBHP " , 3 ) ;
2019-05-24 08:50:40 -05:00
auto res = def . eval ( context ) ;
2020-09-29 06:54:21 -05:00
BOOST_CHECK_EQUAL ( res . size ( ) , 3U ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( res [ " W1 " ] . get ( ) , 11 ) ;
BOOST_CHECK_EQUAL ( res [ " W2 " ] . get ( ) , 2 ) ;
BOOST_CHECK_EQUAL ( res [ " W3 " ] . get ( ) , 3 ) ;
2020-10-15 04:39:07 -05:00
BOOST_CHECK_THROW ( context . get_well_var ( " W3 " , " WWCT " ) , std : : exception ) ;
auto empty_value = context . get_well_var ( " NO_SUCH_WELL " , " WBHP " ) ;
BOOST_CHECK ( ! empty_value ) ;
2019-03-07 03:54:56 -06:00
}
{
2020-11-15 03:03:34 -06:00
UDQDefine def ( udqp , " WUBHP " , 0 , location , { " WBHP " , " 'P*' " } ) ;
2021-02-28 10:04:35 -06:00
SummaryState st ( TimeService : : now ( ) ) ;
2020-08-31 00:38:52 -05:00
UDQState udq_state ( udqp . undefinedValue ( ) ) ;
2023-01-10 03:44:15 -06:00
WellMatcher wm ( NameOrder ( { " I1 " , " I2 " , " P1 " , " P2 " } ) ) ;
2023-01-19 06:20:52 -06:00
auto segmentMatcherFactory = [ ] ( ) { return std : : make_unique < SegmentMatcher > ( ScheduleState { } ) ; } ;
2023-10-23 08:07:23 -05:00
UDQContext context ( udqft , wm , { } , segmentMatcherFactory , st , udq_state ) ;
2019-03-07 03:54:56 -06:00
2019-05-12 03:01:26 -05:00
st . update_well_var ( " P1 " , " WBHP " , 1 ) ;
st . update_well_var ( " P2 " , " WBHP " , 2 ) ;
st . update_well_var ( " I1 " , " WBHP " , 1 ) ;
st . update_well_var ( " I2 " , " WBHP " , 2 ) ;
2019-05-24 08:50:40 -05:00
auto res = def . eval ( context ) ;
2020-09-29 06:54:21 -05:00
BOOST_CHECK_EQUAL ( res . size ( ) , 4U ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( res [ " P1 " ] . get ( ) , 1 ) ;
BOOST_CHECK_EQUAL ( res [ " P2 " ] . get ( ) , 2 ) ;
2019-03-07 03:54:56 -06:00
BOOST_CHECK_EQUAL ( res [ " I1 " ] . defined ( ) , false ) ;
BOOST_CHECK_EQUAL ( res [ " I1 " ] . defined ( ) , false ) ;
}
{
2020-11-15 03:03:34 -06:00
UDQDefine def ( udqp , " WUBHP " , 0 , location , { " NINT " , " ( " , " WBHP " , " ) " }) ;
2021-02-28 10:04:35 -06:00
SummaryState st ( TimeService : : now ( ) ) ;
2020-08-31 00:38:52 -05:00
UDQState udq_state ( udqp . undefinedValue ( ) ) ;
2023-01-10 03:44:15 -06:00
WellMatcher wm ( NameOrder ( { " P1 " , " P2 " , " I1 " , " I2 " } ) ) ;
2023-01-19 06:20:52 -06:00
auto segmentMatcherFactory = [ ] ( ) { return std : : make_unique < SegmentMatcher > ( ScheduleState { } ) ; } ;
2023-10-23 08:07:23 -05:00
UDQContext context ( udqft , wm , { } , segmentMatcherFactory , st , udq_state ) ;
2019-05-12 03:01:26 -05:00
st . update_well_var ( " P1 " , " WBHP " , 4 ) ;
st . update_well_var ( " P2 " , " WBHP " , 3 ) ;
st . update_well_var ( " I1 " , " WBHP " , 2 ) ;
st . update_well_var ( " I2 " , " WBHP " , 1 ) ;
2019-03-07 03:54:56 -06:00
2019-05-24 08:50:40 -05:00
auto res = def . eval ( context ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( res [ " P1 " ] . get ( ) , 4 ) ;
BOOST_CHECK_EQUAL ( res [ " P2 " ] . get ( ) , 3 ) ;
BOOST_CHECK_EQUAL ( res [ " I1 " ] . get ( ) , 2 ) ;
BOOST_CHECK_EQUAL ( res [ " I2 " ] . get ( ) , 1 ) ;
2019-03-07 03:54:56 -06:00
}
}
2018-03-23 06:41:26 -05:00
BOOST_AUTO_TEST_CASE ( KEYWORDS ) {
const std : : string input = R " (
RUNSPEC
UDQDIMS
2019-02-21 01:36:19 -06:00
10 * ' N ' /
2018-03-23 06:41:26 -05:00
UDQPARAM
3 * 0.25 /
) " ;
Parser parser ;
2019-01-03 11:05:19 -06:00
auto deck = parser . parseString ( input ) ;
2018-03-23 06:41:26 -05:00
auto runspec = Runspec ( deck ) ;
2019-01-28 08:17:10 -06:00
auto udq_params = runspec . udqParams ( ) ;
2018-03-23 06:41:26 -05:00
2019-01-28 08:17:10 -06:00
BOOST_CHECK_EQUAL ( 0.25 , udq_params . cmpEpsilon ( ) ) ;
2019-02-21 01:36:19 -06:00
2019-02-21 01:36:57 -06:00
// The reseed parameter is set to false, so the repeated calls to reseedRNG() should have
2019-02-21 01:36:19 -06:00
// no effect.
udq_params . reseedRNG ( 100 ) ;
auto r1 = udq_params . true_rng ( ) ( ) ;
udq_params . reseedRNG ( 100 ) ;
auto r2 = udq_params . true_rng ( ) ( ) ;
BOOST_CHECK ( r1 ! = r2 ) ;
2018-03-23 06:41:26 -05:00
}
2018-04-05 10:39:02 -05:00
2019-02-21 05:23:29 -06:00
BOOST_AUTO_TEST_CASE ( ENUM_CONVERSION ) {
BOOST_CHECK_THROW ( UDQ : : varType ( " WWCT " ) , std : : invalid_argument ) ;
BOOST_CHECK_THROW ( UDQ : : varType ( " XUCT " ) , std : : invalid_argument ) ;
BOOST_CHECK ( UDQ : : varType ( " WUBHP " ) = = UDQVarType : : WELL_VAR ) ;
BOOST_CHECK ( UDQ : : varType ( " GUBHP " ) = = UDQVarType : : GROUP_VAR ) ;
BOOST_CHECK ( UDQ : : varType ( " CUBHP " ) = = UDQVarType : : CONNECTION_VAR ) ;
BOOST_CHECK ( UDQ : : varType ( " FUBHP " ) = = UDQVarType : : FIELD_VAR ) ;
BOOST_CHECK ( UDQ : : varType ( " RUBHP " ) = = UDQVarType : : REGION_VAR ) ;
BOOST_CHECK ( UDQ : : varType ( " AUBHP " ) = = UDQVarType : : AQUIFER_VAR ) ;
BOOST_CHECK ( UDQ : : varType ( " SUBHP " ) = = UDQVarType : : SEGMENT_VAR ) ;
2019-03-07 03:54:56 -06:00
2019-05-24 08:50:40 -05:00
BOOST_CHECK ( UDQ : : targetType ( " WBHP " ) = = UDQVarType : : WELL_VAR ) ;
BOOST_CHECK ( UDQ : : targetType ( " GBHP " ) = = UDQVarType : : GROUP_VAR ) ;
BOOST_CHECK ( UDQ : : targetType ( " CBHP " ) = = UDQVarType : : CONNECTION_VAR ) ;
BOOST_CHECK ( UDQ : : targetType ( " FBHP " ) = = UDQVarType : : FIELD_VAR ) ;
BOOST_CHECK ( UDQ : : targetType ( " RBHP " ) = = UDQVarType : : REGION_VAR ) ;
BOOST_CHECK ( UDQ : : targetType ( " ABHP " ) = = UDQVarType : : AQUIFER_VAR ) ;
BOOST_CHECK ( UDQ : : targetType ( " SBHP " ) = = UDQVarType : : SEGMENT_VAR ) ;
2019-03-07 03:54:56 -06:00
BOOST_REQUIRE_THROW ( UDQ : : actionType ( " INVALID_ACTION " ) , std : : invalid_argument ) ;
BOOST_CHECK ( UDQ : : actionType ( " DEFINE " ) = = UDQAction : : DEFINE ) ;
BOOST_CHECK ( UDQ : : actionType ( " UNITS " ) = = UDQAction : : UNITS ) ;
BOOST_CHECK ( UDQ : : actionType ( " ASSIGN " ) = = UDQAction : : ASSIGN ) ;
2019-02-21 05:23:29 -06:00
}
2018-04-05 10:39:02 -05:00
BOOST_AUTO_TEST_CASE ( UDQ_KEWYORDS ) {
const std : : string input = R " (
RUNSPEC
UDQDIMS
10 * ' Y ' /
UDQPARAM
3 * 0.25 /
SCHEDULE
UDQ
ASSIGN WUBHP 0.0 /
UNITS WUBHP ' BARSA ' /
DEFINE FUOPR AVEG ( WOPR ) + 1 /
2019-03-09 02:46:59 -06:00
ASSIGN WUXUNIT 0.0 /
2019-03-07 03:54:56 -06:00
DEFINE FUOPR AVEG ( WOPR ) /
2018-04-05 10:39:02 -05:00
/
2019-01-28 09:52:28 -06:00
DATES
10 ' JAN ' 2010 /
/
UDQ
ASSIGN WUBHP 0.0 /
2019-03-07 03:54:56 -06:00
DEFINE FUOPR AVEG ( WOPR ) /
2019-01-28 09:52:28 -06:00
UNITS WUBHP ' BARSA ' / - - Repeating the same unit multiple times is superfluous but OK
/
2018-04-05 10:39:02 -05:00
) " ;
2019-01-28 09:52:28 -06:00
auto schedule = make_schedule ( input ) ;
const auto & udq = schedule . getUDQConfig ( 0 ) ;
2020-09-29 06:54:21 -05:00
BOOST_CHECK_EQUAL ( 2U , udq . assignments ( ) . size ( ) ) ;
2018-04-05 10:39:02 -05:00
2019-01-28 09:52:28 -06:00
BOOST_CHECK_THROW ( udq . unit ( " NO_SUCH_KEY " ) , std : : invalid_argument ) ;
BOOST_CHECK_EQUAL ( udq . unit ( " WUBHP " ) , " BARSA " ) ;
2019-03-09 02:46:59 -06:00
BOOST_CHECK ( udq . has_keyword ( " WUBHP " ) ) ;
BOOST_CHECK ( ! udq . has_keyword ( " NO_SUCH_KEY " ) ) ;
BOOST_CHECK ( ! udq . has_unit ( " WUXUNIT " ) ) ;
BOOST_CHECK ( udq . has_unit ( " WUBHP " ) ) ;
2019-01-29 13:11:39 -06:00
Parser parser ;
auto deck = parser . parseString ( input ) ;
2019-02-21 01:36:19 -06:00
auto udq_params1 = UDQParams ( deck ) ;
BOOST_CHECK_EQUAL ( 0.25 , udq_params1 . cmpEpsilon ( ) ) ;
auto & sim_rng1 = udq_params1 . sim_rng ( ) ;
auto & true_rng1 = udq_params1 . true_rng ( ) ;
auto udq_params2 = UDQParams ( deck ) ;
auto & sim_rng2 = udq_params2 . sim_rng ( ) ;
auto & true_rng2 = udq_params2 . true_rng ( ) ;
BOOST_CHECK ( sim_rng1 ( ) = = sim_rng2 ( ) ) ;
BOOST_CHECK ( true_rng1 ( ) ! = true_rng2 ( ) ) ;
udq_params1 . reseedRNG ( 100 ) ;
udq_params2 . reseedRNG ( 100 ) ;
BOOST_CHECK ( true_rng1 ( ) = = true_rng2 ( ) ) ;
2019-01-28 09:52:28 -06:00
}
BOOST_AUTO_TEST_CASE ( UDQ_CHANGE_UNITS_ILLEGAL ) {
const std : : string input = R " (
RUNSPEC
UDQDIMS
10 * ' Y ' /
UDQPARAM
3 * 0.25 /
SCHEDULE
UDQ
ASSIGN WUBHP 0.0 /
UNITS WUBHP ' BARSA ' /
DEFINE FUOPR AVEG ( WOPR ) + 1 /
/
DATES
10 ' JAN ' 2010 /
/
UDQ
ASSIGN WUBHP 0.0 /
DEFINE FUOPR AVEG ( WOPR ) + 1 /
UNITS WUBHP ' HOURS ' / - - Changing unit runtime is * not * supported
/
) " ;
2020-10-05 04:06:19 -05:00
BOOST_CHECK_THROW ( make_schedule ( input ) , std : : exception ) ;
2018-04-05 10:39:02 -05:00
}
2019-03-04 11:20:51 -06:00
BOOST_AUTO_TEST_CASE ( UDQ_DEFINE_WITH_SLASH ) {
const std : : string input = R " (
UDQ
DEFINE WUWCT WWPR / ( WWPR + WOPR ) /
/
) " ;
Parser parser ;
auto deck = parser . parseString ( input ) ;
2021-11-16 07:26:04 -06:00
const auto & udq = deck [ " UDQ " ] . back ( ) ;
2019-03-04 11:20:51 -06:00
const auto & record = udq . getRecord ( 0 ) ;
const auto & data_item = record . getItem ( " DATA " ) ;
2020-04-20 23:51:25 -05:00
const auto & data = RawString : : strings ( data_item . getData < RawString > ( ) ) ;
2019-03-04 11:20:51 -06:00
std : : vector < std : : string > exp = { " WWPR " , " / " , " ( " , " WWPR " , " + " , " WOPR " , " ) " } ;
BOOST_CHECK_EQUAL_COLLECTIONS ( data . begin ( ) , data . end ( ) ,
exp . begin ( ) , exp . end ( ) ) ;
}
2019-02-18 08:08:36 -06:00
BOOST_AUTO_TEST_CASE ( UDQ_ASSIGN_DATA ) {
const std : : string input = R " (
RUNSPEC
UDQDIMS
10 * ' Y ' /
UDQPARAM
3 * 0.25 /
SCHEDULE
UDQ
ASSIGN WU1 P12 4.0 /
ASSIGN WU2 8.0 /
/
) " ;
const auto schedule = make_schedule ( input ) ;
const auto & udq = schedule . getUDQConfig ( 0 ) ;
const auto & assignments = udq . assignments ( ) ;
const auto & ass0 = assignments [ 0 ] ;
const auto & ass1 = assignments [ 1 ] ;
2019-06-24 09:04:48 -05:00
auto w1 = ass0 . eval ( { " P1 " , " P2 " , " P12 " } ) ;
auto w2 = ass1 . eval ( { " P1 " , " P2 " , " P12 " } ) ;
BOOST_CHECK_EQUAL ( w1 . name ( ) , " WU1 " ) ;
BOOST_CHECK_EQUAL ( w2 . name ( ) , " WU2 " ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( w1 [ " P12 " ] . get ( ) , 4.0 ) ;
2019-06-24 09:04:48 -05:00
BOOST_CHECK_EQUAL ( w1 [ " P1 " ] . defined ( ) , false ) ;
BOOST_CHECK_EQUAL ( w1 [ " P2 " ] . defined ( ) , false ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( w2 [ " P12 " ] . get ( ) , 8.0 ) ;
BOOST_CHECK_EQUAL ( w2 [ " P1 " ] . get ( ) , 8.0 ) ;
BOOST_CHECK_EQUAL ( w2 [ " P2 " ] . get ( ) , 8.0 ) ;
2019-02-18 08:08:36 -06:00
}
2019-01-29 13:11:39 -06:00
BOOST_AUTO_TEST_CASE ( UDQ_CONTEXT ) {
2021-02-28 10:04:35 -06:00
SummaryState st ( TimeService : : now ( ) ) ;
2019-03-07 03:32:35 -06:00
UDQFunctionTable func_table ;
2019-06-20 04:20:47 -05:00
UDQParams udqp ;
2020-08-31 00:38:52 -05:00
UDQState udq_state ( udqp . undefinedValue ( ) ) ;
2023-01-19 06:20:52 -06:00
auto segmentMatcherFactory = [ ] ( ) { return std : : make_unique < SegmentMatcher > ( ScheduleState { } ) ; } ;
2023-10-23 08:07:23 -05:00
UDQContext ctx ( func_table , { } , { } , segmentMatcherFactory , st , udq_state ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( * ctx . get ( " JAN " ) , 1.0 ) ;
2020-09-08 01:19:17 -05:00
BOOST_CHECK_THROW ( ctx . get ( " NO_SUCH_KEY " ) , std : : out_of_range ) ;
2019-01-29 13:11:39 -06:00
2020-11-15 03:02:34 -06:00
for ( std : : string & key : std : : vector < std : : string > ( { " MSUMLINS " , " MSUMNEWT " , " NEWTON " , " TCPU " } ) )
2019-01-29 13:11:39 -06:00
BOOST_CHECK_NO_THROW ( ctx . get ( key ) ) ;
2020-08-31 00:38:52 -05:00
st . update ( " SX:KEY " , 1.0 ) ;
BOOST_CHECK_EQUAL ( * ctx . get ( " SX:KEY " ) , 1.0 ) ;
2019-01-29 13:11:39 -06:00
}
2019-02-14 03:36:21 -06:00
BOOST_AUTO_TEST_CASE ( UDQ_SET ) {
2019-02-21 03:36:20 -06:00
UDQSet s1 ( " NAME " , 5 ) ;
2019-02-14 03:36:21 -06:00
for ( const auto & v : s1 ) {
BOOST_CHECK_EQUAL ( false , v . defined ( ) ) ;
2020-08-31 00:38:52 -05:00
BOOST_REQUIRE_THROW ( v . get ( ) , std : : invalid_argument ) ;
2019-02-14 03:36:21 -06:00
}
2020-09-29 06:54:21 -05:00
BOOST_CHECK_EQUAL ( s1 . defined_size ( ) , 0U ) ;
2019-02-14 03:36:21 -06:00
s1 . assign ( 1 ) ;
for ( const auto & v : s1 ) {
BOOST_CHECK_EQUAL ( true , v . defined ( ) ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( v . get ( ) , 1.0 ) ;
2019-02-14 03:36:21 -06:00
}
BOOST_CHECK_EQUAL ( s1 . defined_size ( ) , s1 . size ( ) ) ;
s1 . assign ( 0 , 0.0 ) ;
{
2019-02-21 03:36:20 -06:00
UDQSet s2 ( " NAME " , 6 ) ;
2019-12-13 08:59:04 -06:00
BOOST_REQUIRE_THROW ( s1 + s2 , std : : logic_error ) ;
2019-02-14 03:36:21 -06:00
}
{
2019-02-21 03:36:20 -06:00
UDQSet s2 ( " NAME " , 5 ) ;
2019-02-14 03:36:21 -06:00
s2 . assign ( 0 , 25 ) ;
auto s3 = s1 + s2 ;
auto v0 = s3 [ 0 ] ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( v0 . get ( ) , 25 ) ;
2019-02-14 03:36:21 -06:00
auto v4 = s3 [ 4 ] ;
BOOST_CHECK ( ! v4 . defined ( ) ) ;
}
s1 . assign ( 0 , 1.0 ) ;
{
UDQSet s2 = s1 + 1.0 ;
UDQSet s3 = s2 * 2.0 ;
UDQSet s4 = s1 - 1.0 ;
for ( const auto & v : s2 ) {
BOOST_CHECK_EQUAL ( true , v . defined ( ) ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( v . get ( ) , 2.0 ) ;
2019-02-14 03:36:21 -06:00
}
for ( const auto & v : s3 ) {
BOOST_CHECK_EQUAL ( true , v . defined ( ) ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( v . get ( ) , 4.0 ) ;
2019-02-14 03:36:21 -06:00
}
for ( const auto & v : s4 ) {
BOOST_CHECK_EQUAL ( true , v . defined ( ) ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( v . get ( ) , 0 ) ;
2019-02-14 03:36:21 -06:00
}
}
}
2019-02-21 01:36:57 -06:00
BOOST_AUTO_TEST_CASE ( UDQ_FUNCTION_TABLE ) {
2019-03-07 03:48:05 -06:00
UDQFunctionTable udqft ;
2019-02-21 01:36:57 -06:00
BOOST_CHECK ( udqft . has_function ( " SUM " ) ) ;
BOOST_CHECK ( ! udqft . has_function ( " NO_SUCH_FUNCTION " ) ) ;
2019-02-21 03:36:20 -06:00
UDQSet arg ( " NAME " , 5 ) ;
2019-02-21 01:36:57 -06:00
arg . assign ( 0 , 1 ) ;
arg . assign ( 2 , 2 ) ;
arg . assign ( 4 , 4 ) ;
{
const auto & func = dynamic_cast < const UDQScalarFunction & > ( udqft . get ( " SUM " ) ) ;
auto result = func . eval ( arg ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( result [ 0 ] . get ( ) , 7 ) ;
2019-02-21 01:36:57 -06:00
}
{
const auto & func = dynamic_cast < const UDQScalarFunction & > ( udqft . get ( " NORM1 " ) ) ;
auto result = func . eval ( arg ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( result [ 0 ] . get ( ) , 7 ) ;
2019-02-21 01:36:57 -06:00
}
{
const auto & func = dynamic_cast < const UDQScalarFunction & > ( udqft . get ( " NORM2 " ) ) ;
auto result = func . eval ( arg ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( result [ 0 ] . get ( ) , std : : sqrt ( 1 + 4 + 16 ) ) ;
2019-02-21 01:36:57 -06:00
}
{
const auto & func = dynamic_cast < const UDQScalarFunction & > ( udqft . get ( " NORMI " ) ) ;
auto result = func . eval ( arg ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( result [ 0 ] . get ( ) , 4 ) ;
2019-02-21 01:36:57 -06:00
}
{
const auto & func = dynamic_cast < const UDQScalarFunction & > ( udqft . get ( " MIN " ) ) ;
auto result = func . eval ( arg ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( result [ 0 ] . get ( ) , 1 ) ;
2019-02-21 01:36:57 -06:00
}
{
const auto & func = dynamic_cast < const UDQScalarFunction & > ( udqft . get ( " MAX " ) ) ;
auto result = func . eval ( arg ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( result [ 0 ] . get ( ) , 4 ) ;
2019-02-21 01:36:57 -06:00
}
{
const auto & func = dynamic_cast < const UDQScalarFunction & > ( udqft . get ( " AVEA " ) ) ;
auto result = func . eval ( arg ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( result [ 0 ] . get ( ) , 7.0 / 3 ) ;
2019-02-21 01:36:57 -06:00
}
{
const auto & func = dynamic_cast < const UDQScalarFunction & > ( udqft . get ( " AVEG " ) ) ;
auto result = func . eval ( arg ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( result [ 0 ] . get ( ) , std : : exp ( ( std : : log ( 1 ) + std : : log ( 2.0 ) + std : : log ( 4 ) ) / 3 ) ) ;
2019-02-21 01:36:57 -06:00
}
{
const auto & func = dynamic_cast < const UDQScalarFunction & > ( udqft . get ( " PROD " ) ) ;
auto result = func . eval ( arg ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( result [ 0 ] . get ( ) , 8.0 ) ;
2019-02-21 01:36:57 -06:00
}
{
2019-02-21 03:36:20 -06:00
UDQSet arg2 ( " NAME " , 4 ) ;
2019-02-21 01:36:57 -06:00
arg2 . assign ( 0 , 1 ) ;
arg2 . assign ( 2 , 4 ) ;
arg2 . assign ( 3 , 4 ) ;
const auto & func = dynamic_cast < const UDQScalarFunction & > ( udqft . get ( " AVEH " ) ) ;
auto result = func . eval ( arg2 ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( result [ 0 ] . get ( ) , 2.0 ) ;
2019-02-21 01:36:57 -06:00
}
}
BOOST_AUTO_TEST_CASE ( CMP_FUNCTIONS ) {
2019-03-07 03:48:05 -06:00
UDQFunctionTable udqft ;
2019-02-21 03:36:20 -06:00
UDQSet arg1 ( " NAME " , 5 ) ;
UDQSet arg2 ( " NAME " , 5 ) ;
UDQSet arg3 ( " NAME " , 3 ) ;
2019-02-21 01:36:57 -06:00
arg1 . assign ( 1 , 1 ) ;
arg1 . assign ( 0 , 1 ) ;
arg1 . assign ( 2 , 2 ) ;
arg1 . assign ( 4 , 4 ) ;
arg2 . assign ( 0 , 0.9 ) ;
arg2 . assign ( 2 , 2.5 ) ;
arg2 . assign ( 4 , 4.0 ) ;
2019-12-13 08:59:04 -06:00
BOOST_CHECK_THROW ( UDQBinaryFunction : : EQ ( 0.25 , arg1 , arg3 ) , std : : logic_error ) ;
2019-02-21 01:36:57 -06:00
{
auto result = UDQBinaryFunction : : EQ ( 0 , arg1 , arg2 ) ;
2020-09-29 06:54:21 -05:00
BOOST_CHECK_EQUAL ( result . defined_size ( ) , 3U ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( result [ 0 ] . get ( ) , 0 ) ;
BOOST_CHECK_EQUAL ( result [ 2 ] . get ( ) , 0 ) ;
BOOST_CHECK_EQUAL ( result [ 4 ] . get ( ) , 1 ) ;
2019-02-21 01:36:57 -06:00
result = UDQBinaryFunction : : EQ ( 0.20 , arg1 , arg2 ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( result [ 0 ] . get ( ) , 1 ) ;
BOOST_CHECK_EQUAL ( result [ 2 ] . get ( ) , 0 ) ;
BOOST_CHECK_EQUAL ( result [ 4 ] . get ( ) , 1 ) ;
2019-02-21 01:36:57 -06:00
const auto & func = dynamic_cast < const UDQBinaryFunction & > ( udqft . get ( " == " ) ) ;
result = func . eval ( arg1 , arg2 ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( result [ 0 ] . get ( ) , 0 ) ;
BOOST_CHECK_EQUAL ( result [ 2 ] . get ( ) , 0 ) ;
BOOST_CHECK_EQUAL ( result [ 4 ] . get ( ) , 1 ) ;
2019-02-21 01:36:57 -06:00
}
{
const auto & func = dynamic_cast < const UDQBinaryFunction & > ( udqft . get ( " < " ) ) ;
auto result = func . eval ( arg1 , arg2 ) ;
2020-09-29 06:54:21 -05:00
BOOST_CHECK_EQUAL ( result . defined_size ( ) , 3U ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( result [ 0 ] . get ( ) , 0 ) ;
BOOST_CHECK_EQUAL ( result [ 2 ] . get ( ) , 1 ) ;
BOOST_CHECK_EQUAL ( result [ 4 ] . get ( ) , 0 ) ;
2019-02-21 01:36:57 -06:00
}
{
const auto & func = dynamic_cast < const UDQBinaryFunction & > ( udqft . get ( " > " ) ) ;
auto result = func . eval ( arg1 , arg2 ) ;
2020-09-29 06:54:21 -05:00
BOOST_CHECK_EQUAL ( result . defined_size ( ) , 3U ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( result [ 0 ] . get ( ) , 1 ) ;
BOOST_CHECK_EQUAL ( result [ 2 ] . get ( ) , 0 ) ;
BOOST_CHECK_EQUAL ( result [ 4 ] . get ( ) , 0 ) ;
2019-02-21 01:36:57 -06:00
}
{
const auto & func = dynamic_cast < const UDQBinaryFunction & > ( udqft . get ( " ^ " ) ) ;
2019-06-22 17:02:23 -05:00
UDQSet arg1_local ( " NAME " , 4 ) ;
UDQSet arg2_local ( " NAME " , 4 ) ;
2019-02-21 01:36:57 -06:00
2019-06-22 17:02:23 -05:00
for ( std : : size_t i = 0 ; i < arg1_local . size ( ) ; i + + ) {
arg1_local . assign ( i , i + 1 ) ;
arg2_local . assign ( i , 2 ) ;
2019-02-21 01:36:57 -06:00
}
2019-06-22 17:02:23 -05:00
auto result = func . eval ( arg1_local , arg2_local ) ;
for ( std : : size_t i = 0 ; i < arg1_local . size ( ) ; i + + )
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( result [ i ] . get ( ) , ( i + 1 ) * ( i + 1 ) ) ;
2019-02-21 01:36:57 -06:00
}
{
auto result = UDQBinaryFunction : : GE ( 1.0 , arg1 , arg2 ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( result [ 0 ] . get ( ) , 1 ) ;
2019-02-21 01:36:57 -06:00
// This is bisarre - but due to the large epsilon 2 and 2.5 compare as
// equal; and then we evaluate 2 >= 2.5 as TRUE!
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( result [ 2 ] . get ( ) , 1 ) ;
BOOST_CHECK_EQUAL ( result [ 4 ] . get ( ) , 1 ) ;
2019-02-21 01:36:57 -06:00
}
{
const auto & func = dynamic_cast < const UDQBinaryFunction & > ( udqft . get ( " <= " ) ) ;
auto result = func . eval ( arg1 , arg2 ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( result [ 0 ] . get ( ) , 0 ) ;
BOOST_CHECK_EQUAL ( result [ 2 ] . get ( ) , 1 ) ;
BOOST_CHECK_EQUAL ( result [ 4 ] . get ( ) , 1 ) ;
2019-02-21 01:36:57 -06:00
}
}
2020-08-31 00:38:52 -05:00
BOOST_AUTO_TEST_CASE ( CMP_FUNCTIONS2 ) {
UDQFunctionTable udqft ;
auto arg1 = UDQSet : : scalar ( " NAME " , 0 ) ;
auto arg2 = UDQSet : : scalar ( " NAME " , 0 ) ;
auto eq = UDQBinaryFunction : : EQ ( 0 , arg1 , arg2 ) ;
BOOST_CHECK_EQUAL ( eq [ 0 ] . get ( ) , 1 ) ;
}
2019-02-21 01:36:57 -06:00
BOOST_AUTO_TEST_CASE ( ELEMENTAL_UNARY_FUNCTIONS ) {
2019-03-07 03:48:05 -06:00
UDQFunctionTable udqft ;
2019-02-21 03:36:20 -06:00
UDQSet arg ( " NAME " , 5 ) ;
2019-02-21 01:36:57 -06:00
arg . assign ( 0 , 1 ) ;
arg . assign ( 2 , 2 ) ;
arg . assign ( 4 , 4 ) ;
{
const auto & func = dynamic_cast < const UDQUnaryElementalFunction & > ( udqft . get ( " ABS " ) ) ;
2019-02-21 03:36:20 -06:00
UDQSet arg2 ( " NAME " , 5 ) ;
2019-02-21 01:36:57 -06:00
arg2 . assign ( 0 , 1 ) ;
arg2 . assign ( 2 , - 2 ) ;
arg2 . assign ( 4 , 4 ) ;
auto result = func . eval ( arg2 ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( result [ 0 ] . get ( ) , 1 ) ;
BOOST_CHECK_EQUAL ( result [ 2 ] . get ( ) , 2 ) ;
BOOST_CHECK_EQUAL ( result [ 4 ] . get ( ) , 4 ) ;
2019-02-21 01:36:57 -06:00
}
{
const auto & func = dynamic_cast < const UDQUnaryElementalFunction & > ( udqft . get ( " DEF " ) ) ;
auto result = func . eval ( arg ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( result [ 0 ] . get ( ) , 1 ) ;
BOOST_CHECK_EQUAL ( result [ 2 ] . get ( ) , 1 ) ;
BOOST_CHECK_EQUAL ( result [ 4 ] . get ( ) , 1 ) ;
2019-02-21 01:36:57 -06:00
}
{
const auto & func = dynamic_cast < const UDQUnaryElementalFunction & > ( udqft . get ( " UNDEF " ) ) ;
auto result = func . eval ( arg ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( result [ 1 ] . get ( ) , 1 ) ;
BOOST_CHECK_EQUAL ( result [ 3 ] . get ( ) , 1 ) ;
2020-09-29 06:54:21 -05:00
BOOST_CHECK_EQUAL ( result . defined_size ( ) , 2U ) ;
2019-02-21 01:36:57 -06:00
}
{
const auto & func = dynamic_cast < const UDQUnaryElementalFunction & > ( udqft . get ( " EXP " ) ) ;
auto result = func . eval ( arg ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( result [ 0 ] . get ( ) , std : : exp ( 1 ) ) ;
BOOST_CHECK_EQUAL ( result [ 2 ] . get ( ) , std : : exp ( 2 ) ) ;
BOOST_CHECK_EQUAL ( result [ 4 ] . get ( ) , std : : exp ( 4 ) ) ;
2019-02-21 01:36:57 -06:00
}
{
const auto & func = dynamic_cast < const UDQUnaryElementalFunction & > ( udqft . get ( " IDV " ) ) ;
auto result = func . eval ( arg ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( result [ 0 ] . get ( ) , 1 ) ;
BOOST_CHECK_EQUAL ( result [ 1 ] . get ( ) , 0 ) ;
BOOST_CHECK_EQUAL ( result [ 2 ] . get ( ) , 1 ) ;
BOOST_CHECK_EQUAL ( result [ 3 ] . get ( ) , 0 ) ;
BOOST_CHECK_EQUAL ( result [ 4 ] . get ( ) , 1 ) ;
2019-02-21 01:36:57 -06:00
}
{
const auto & func = dynamic_cast < const UDQUnaryElementalFunction & > ( udqft . get ( " LOG " ) ) ;
2019-06-22 17:02:23 -05:00
UDQSet arg_local ( " NAME " , 3 ) ;
arg_local . assign ( 0 , 10 ) ;
arg_local . assign ( 2 , 1000 ) ;
2019-02-21 01:36:57 -06:00
2019-06-22 17:02:23 -05:00
auto result = func . eval ( arg_local ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( result [ 0 ] . get ( ) , 1 ) ;
2019-02-21 01:36:57 -06:00
BOOST_CHECK ( ! result [ 1 ] ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( result [ 2 ] . get ( ) , 3 ) ;
2019-02-21 01:36:57 -06:00
}
{
const auto & func = dynamic_cast < const UDQUnaryElementalFunction & > ( udqft . get ( " NINT " ) ) ;
2019-06-22 17:02:23 -05:00
UDQSet arg_local ( " NAME " , 3 ) ;
arg_local . assign ( 0 , 0.75 ) ;
arg_local . assign ( 2 , 1.25 ) ;
2019-02-21 01:36:57 -06:00
2019-06-22 17:02:23 -05:00
auto result = func . eval ( arg_local ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( result [ 0 ] . get ( ) , 1 ) ;
2019-02-21 01:36:57 -06:00
BOOST_CHECK ( ! result [ 1 ] ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( result [ 2 ] . get ( ) , 1 ) ;
2019-02-21 01:36:57 -06:00
}
{
const auto & func = dynamic_cast < const UDQUnaryElementalFunction & > ( udqft . get ( " RANDN " ) ) ;
2019-06-22 17:02:23 -05:00
UDQSet arg_local ( " NAME " , 3 ) ;
arg_local . assign ( 0 , - 1.0 ) ;
arg_local . assign ( 2 , - 1.0 ) ;
2019-02-21 01:36:57 -06:00
2019-06-22 17:02:23 -05:00
auto result1 = func . eval ( arg_local ) ;
auto result2 = func . eval ( arg_local ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK ( result1 [ 0 ] . get ( ) ! = - 1.0 ) ;
2019-02-21 01:36:57 -06:00
BOOST_CHECK ( ! result1 [ 1 ] ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK ( result1 [ 2 ] . get ( ) ! = - 1.0 ) ;
2019-02-21 01:36:57 -06:00
2020-08-31 00:38:52 -05:00
BOOST_CHECK ( result1 [ 0 ] . get ( ) ! = result2 [ 0 ] . get ( ) ) ;
BOOST_CHECK ( result1 [ 2 ] . get ( ) ! = result2 [ 2 ] . get ( ) ) ;
2019-02-21 01:36:57 -06:00
}
{
const auto & func = dynamic_cast < const UDQUnaryElementalFunction & > ( udqft . get ( " SORTA " ) ) ;
auto result = func . eval ( arg ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( result [ 0 ] . get ( ) , 1 ) ;
2019-02-21 01:36:57 -06:00
BOOST_CHECK ( ! result [ 1 ] ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( result [ 2 ] . get ( ) , 2 ) ;
2019-02-21 01:36:57 -06:00
BOOST_CHECK ( ! result [ 3 ] ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( result [ 4 ] . get ( ) , 3 ) ;
2019-02-21 01:36:57 -06:00
}
{
const auto & func = dynamic_cast < const UDQUnaryElementalFunction & > ( udqft . get ( " SORTD " ) ) ;
auto result = func . eval ( arg ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( result [ 0 ] . get ( ) , 3 ) ;
2019-02-21 01:36:57 -06:00
BOOST_CHECK ( ! result [ 1 ] ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( result [ 2 ] . get ( ) , 2 ) ;
2019-02-21 01:36:57 -06:00
BOOST_CHECK ( ! result [ 3 ] ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( result [ 4 ] . get ( ) , 1 ) ;
2019-02-21 01:36:57 -06:00
}
}
BOOST_AUTO_TEST_CASE ( UNION_FUNCTIONS ) {
2019-03-07 03:48:05 -06:00
UDQFunctionTable udqft ;
2019-02-21 03:36:20 -06:00
UDQSet arg1 ( " NAME " , 5 ) ;
UDQSet arg2 ( " NAME " , 5 ) ;
2019-02-21 01:36:57 -06:00
arg1 . assign ( 0 , 1 ) ;
arg1 . assign ( 2 , 2 ) ;
arg2 . assign ( 0 , 1.0 ) ;
arg2 . assign ( 3 , 3 ) ;
const auto & func = dynamic_cast < const UDQBinaryFunction & > ( udqft . get ( " UADD " ) ) ;
auto result = func . eval ( arg1 , arg2 ) ;
2020-09-29 06:54:21 -05:00
BOOST_CHECK_EQUAL ( 3U , result . defined_size ( ) ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( 2 , result [ 0 ] . get ( ) ) ;
BOOST_CHECK_EQUAL ( 2 , result [ 2 ] . get ( ) ) ;
BOOST_CHECK_EQUAL ( 3 , result [ 3 ] . get ( ) ) ;
2019-02-21 01:36:57 -06:00
}
BOOST_AUTO_TEST_CASE ( FUNCTIONS_INVALID_ARGUMENT ) {
2019-02-21 03:36:20 -06:00
UDQSet arg ( " NAME " , 3 ) ;
2019-02-21 01:36:57 -06:00
arg . assign ( 0 , - 1 ) ;
BOOST_REQUIRE_THROW ( UDQScalarFunction : : AVEG ( arg ) , std : : invalid_argument ) ;
BOOST_REQUIRE_THROW ( UDQUnaryElementalFunction : : LOG ( arg ) , std : : invalid_argument ) ;
BOOST_REQUIRE_THROW ( UDQUnaryElementalFunction : : LN ( arg ) , std : : invalid_argument ) ;
}
2019-02-14 03:36:21 -06:00
BOOST_AUTO_TEST_CASE ( UDQ_SET_DIV ) {
2020-06-11 08:19:47 -05:00
UDQSet s ( " NAME " , 6 ) ;
2019-02-14 03:36:21 -06:00
s . assign ( 0 , 1 ) ;
s . assign ( 2 , 2 ) ;
s . assign ( 4 , 5 ) ;
2020-06-11 08:19:47 -05:00
s . assign ( 5 , 0 ) ;
2019-02-14 03:36:21 -06:00
auto result = 10 / s ;
2020-09-29 06:54:21 -05:00
BOOST_CHECK_EQUAL ( result . defined_size ( ) , 3U ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( result [ 0 ] . get ( ) , 10 ) ;
BOOST_CHECK_EQUAL ( result [ 2 ] . get ( ) , 5 ) ;
BOOST_CHECK_EQUAL ( result [ 4 ] . get ( ) , 2 ) ;
2019-02-14 03:36:21 -06:00
}
2019-02-18 08:08:08 -06:00
2019-02-18 08:08:36 -06:00
BOOST_AUTO_TEST_CASE ( UDQASSIGN_TEST ) {
2021-06-24 09:46:53 -05:00
UDQAssign as1 ( " WUPR " , std : : vector < std : : string > { } , 1.0 , 1 ) ;
UDQAssign as2 ( " WUPR " , std : : vector < std : : string > { " P* " } , 2.0 , 2 ) ;
UDQAssign as3 ( " WUPR " , std : : vector < std : : string > { " P1 " } , 4.0 , 3 ) ;
2019-02-18 08:08:36 -06:00
std : : vector < std : : string > ws1 = { " P1 " , " P2 " , " I1 " , " I2 " } ;
2019-05-24 08:50:40 -05:00
auto res1 = as1 . eval ( ws1 ) ;
2020-09-29 06:54:21 -05:00
BOOST_CHECK_EQUAL ( res1 . size ( ) , 4U ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( res1 [ " P1 " ] . get ( ) , 1.0 ) ;
BOOST_CHECK_EQUAL ( res1 [ " I2 " ] . get ( ) , 1.0 ) ;
2019-02-18 08:08:36 -06:00
2019-05-24 08:50:40 -05:00
auto res2 = as2 . eval ( ws1 ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( res2 [ " P1 " ] . get ( ) , 2.0 ) ;
BOOST_CHECK_EQUAL ( res2 [ " P2 " ] . get ( ) , 2.0 ) ;
2019-02-18 08:08:36 -06:00
BOOST_CHECK ( ! res2 [ " I1 " ] . defined ( ) ) ;
BOOST_CHECK ( ! res2 [ " I2 " ] . defined ( ) ) ;
2019-05-24 08:50:40 -05:00
auto res3 = as3 . eval ( ws1 ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( res3 [ " P1 " ] . get ( ) , 4.0 ) ;
2019-02-18 08:08:36 -06:00
BOOST_CHECK ( ! res3 [ " P2 " ] . defined ( ) ) ;
BOOST_CHECK ( ! res3 [ " I1 " ] . defined ( ) ) ;
BOOST_CHECK ( ! res3 [ " I2 " ] . defined ( ) ) ;
}
2019-03-07 03:54:56 -06:00
2023-01-24 10:14:45 -06:00
BOOST_AUTO_TEST_CASE ( UDQASSIGN_NUMBERED_ITEMS_TEST ) {
using Vsz = std : : vector < std : : size_t > ;
const auto selector = UDQSet : : EnumeratedWellItems {
" PROD01 " , Vsz { 1 , 3 , 5 , 7 }
} ;
const auto as = UDQAssign {
" SUVTRIG " , std : : vector { selector } , 0.123 , 42
} ;
const auto segments = std : : vector {
UDQSet : : EnumeratedWellItems { " PROD01 " , Vsz { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , } } ,
UDQSet : : EnumeratedWellItems { " PROD02 " , Vsz { 1 , 2 , 3 , 4 , 5 , } } ,
UDQSet : : EnumeratedWellItems { " PROD06 " , Vsz { 2 , 4 , 6 , 8 , 10 , } } ,
UDQSet : : EnumeratedWellItems { " I-45 " , Vsz { 1 , 2 , 3 , } } ,
} ;
const auto us = as . eval ( segments ) ;
BOOST_CHECK_EQUAL ( us . size ( ) , std : : size_t { 23 } ) ;
BOOST_CHECK_CLOSE ( us ( " PROD01 " , 1 ) . get ( ) , 0.123 , 1.0e-8 ) ;
BOOST_CHECK_MESSAGE ( ! us ( " PROD01 " , 2 ) . defined ( ) , R " (SUVTRIG( " PROD01 " , 2) must not be defined) " ) ;
BOOST_CHECK_CLOSE ( us ( " PROD01 " , 3 ) . get ( ) , 0.123 , 1.0e-8 ) ;
BOOST_CHECK_MESSAGE ( ! us ( " PROD01 " , 4 ) . defined ( ) , R " (SUVTRIG( " PROD01 " , 4) must not be defined) " ) ;
BOOST_CHECK_CLOSE ( us ( " PROD01 " , 5 ) . get ( ) , 0.123 , 1.0e-8 ) ;
BOOST_CHECK_MESSAGE ( ! us ( " PROD01 " , 6 ) . defined ( ) , R " (SUVTRIG( " PROD01 " , 6) must not be defined) " ) ;
BOOST_CHECK_CLOSE ( us ( " PROD01 " , 7 ) . get ( ) , 0.123 , 1.0e-8 ) ;
BOOST_CHECK_MESSAGE ( ! us ( " PROD01 " , 8 ) . defined ( ) , R " (SUVTRIG( " PROD01 " , 8) must not be defined) " ) ;
BOOST_CHECK_MESSAGE ( ! us ( " PROD01 " , 9 ) . defined ( ) , R " (SUVTRIG( " PROD01 " , 9) must not be defined) " ) ;
BOOST_CHECK_MESSAGE ( ! us ( " PROD01 " , 10 ) . defined ( ) , R " (SUVTRIG( " PROD01 " , 10) must not be defined) " ) ;
BOOST_CHECK_MESSAGE ( ! us ( " PROD02 " , 1 ) . defined ( ) , R " (SUVTRIG( " PROD02 " , 1) must not be defined) " ) ;
BOOST_CHECK_MESSAGE ( ! us ( " PROD02 " , 2 ) . defined ( ) , R " (SUVTRIG( " PROD02 " , 2) must not be defined) " ) ;
BOOST_CHECK_MESSAGE ( ! us ( " PROD02 " , 3 ) . defined ( ) , R " (SUVTRIG( " PROD02 " , 3) must not be defined) " ) ;
BOOST_CHECK_MESSAGE ( ! us ( " PROD02 " , 4 ) . defined ( ) , R " (SUVTRIG( " PROD02 " , 4) must not be defined) " ) ;
BOOST_CHECK_MESSAGE ( ! us ( " PROD02 " , 5 ) . defined ( ) , R " (SUVTRIG( " PROD02 " , 5) must not be defined) " ) ;
BOOST_CHECK_MESSAGE ( ! us ( " PROD06 " , 2 ) . defined ( ) , R " (SUVTRIG( " PROD06 " , 2) must not be defined) " ) ;
BOOST_CHECK_MESSAGE ( ! us ( " PROD06 " , 4 ) . defined ( ) , R " (SUVTRIG( " PROD06 " , 4) must not be defined) " ) ;
BOOST_CHECK_MESSAGE ( ! us ( " PROD06 " , 6 ) . defined ( ) , R " (SUVTRIG( " PROD06 " , 6) must not be defined) " ) ;
BOOST_CHECK_MESSAGE ( ! us ( " PROD06 " , 8 ) . defined ( ) , R " (SUVTRIG( " PROD06 " , 8) must not be defined) " ) ;
BOOST_CHECK_MESSAGE ( ! us ( " PROD06 " , 10 ) . defined ( ) , R " (SUVTRIG( " PROD06 " , 10) must not be defined) " ) ;
2023-05-09 03:34:50 -05:00
BOOST_CHECK_THROW ( us ( " PROD06 " , 3 ) . defined ( ) , std : : out_of_range ) ;
2023-01-24 10:14:45 -06:00
BOOST_CHECK_MESSAGE ( ! us ( " I-45 " , 1 ) . defined ( ) , R " (SUVTRIG( " I - 45 " , 1) must not be defined) " ) ;
BOOST_CHECK_MESSAGE ( ! us ( " I-45 " , 2 ) . defined ( ) , R " (SUVTRIG( " I - 45 " , 2) must not be defined) " ) ;
BOOST_CHECK_MESSAGE ( ! us ( " I-45 " , 3 ) . defined ( ) , R " (SUVTRIG( " I - 45 " , 3) must not be defined) " ) ;
2023-05-09 03:34:50 -05:00
BOOST_CHECK_THROW ( us ( " Hello " , 42 ) . defined ( ) , std : : out_of_range ) ;
2023-01-24 10:14:45 -06:00
}
2019-03-07 03:54:56 -06:00
BOOST_AUTO_TEST_CASE ( UDQ_POW_TEST ) {
2020-09-27 15:13:30 -05:00
KeywordLocation location ;
2019-03-07 03:54:56 -06:00
UDQFunctionTable udqft ;
2019-03-11 05:43:23 -05:00
UDQParams udqp ;
2020-11-15 03:03:34 -06:00
UDQDefine def_pow1 ( udqp , " WU " , 0 , location , { " WOPR " , " + " , " WWPR " , " * " , " WGOR " , " ^ " , " WWIR " } ) ;
UDQDefine def_pow2 ( udqp , " WU " , 0 , location , { " ( " , " WOPR " , " + " , " WWPR " , " ) " , " ^ " , " ( " , " WOPR " , " + " , " WGOR " , " * " , " WWIR " , " - " , " WBHP " , " ) " }) ;
2021-02-28 10:04:35 -06:00
SummaryState st ( TimeService : : now ( ) ) ;
2020-08-31 00:38:52 -05:00
UDQState udq_state ( udqp . undefinedValue ( ) ) ;
2021-01-28 10:47:51 -06:00
NameOrder wo ; wo . add ( " P1 " ) ;
2023-01-10 03:44:15 -06:00
WellMatcher wm ( wo ) ;
2023-01-19 06:20:52 -06:00
auto segmentMatcherFactory = [ ] ( ) { return std : : make_unique < SegmentMatcher > ( ScheduleState { } ) ; } ;
2023-10-23 08:07:23 -05:00
UDQContext context ( udqft , wm , { } , segmentMatcherFactory , st , udq_state ) ;
2019-03-07 03:54:56 -06:00
2019-05-12 03:01:26 -05:00
st . update_well_var ( " P1 " , " WOPR " , 1 ) ;
st . update_well_var ( " P1 " , " WWPR " , 2 ) ;
st . update_well_var ( " P1 " , " WGOR " , 3 ) ;
st . update_well_var ( " P1 " , " WWIR " , 4 ) ;
2020-10-20 13:02:19 -05:00
st . update_well_var ( " P1 " , " WBHP " , 7 ) ;
2019-03-07 03:54:56 -06:00
2019-05-24 08:50:40 -05:00
auto res_pow1 = def_pow1 . eval ( context ) ;
auto res_pow2 = def_pow2 . eval ( context ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( res_pow1 [ " P1 " ] . get ( ) , 1 + 2 * std : : pow ( 3 , 4 ) ) ;
BOOST_CHECK_EQUAL ( res_pow2 [ " P1 " ] . get ( ) , std : : pow ( 1 + 2 , 1 + 3 * 4 - 7 ) ) ;
2019-03-07 03:54:56 -06:00
}
BOOST_AUTO_TEST_CASE ( UDQ_CMP_TEST ) {
2020-09-27 15:13:30 -05:00
KeywordLocation location ;
2019-03-07 03:54:56 -06:00
UDQFunctionTable udqft ;
2019-03-11 05:43:23 -05:00
UDQParams udqp ;
2020-11-15 03:03:34 -06:00
UDQDefine def_cmp ( udqp , " WU " , 0 , location , { " WOPR " , " > " , " WWPR " , " + " , " WGOR " , " * " , " WWIR " } ) ;
2021-02-28 10:04:35 -06:00
SummaryState st ( TimeService : : now ( ) ) ;
2020-08-31 00:38:52 -05:00
UDQState udq_state ( udqp . undefinedValue ( ) ) ;
2023-01-10 03:44:15 -06:00
WellMatcher wm ( NameOrder ( { " P1 " , " P2 " } ) ) ;
2023-01-19 06:20:52 -06:00
auto segmentMatcherFactory = [ ] ( ) { return std : : make_unique < SegmentMatcher > ( ScheduleState { } ) ; } ;
2023-10-23 08:07:23 -05:00
UDQContext context ( udqft , wm , { } , segmentMatcherFactory , st , udq_state ) ;
2019-03-07 03:54:56 -06:00
2019-05-12 03:01:26 -05:00
st . update_well_var ( " P1 " , " WOPR " , 0 ) ;
st . update_well_var ( " P1 " , " WWPR " , 10 ) ;
st . update_well_var ( " P1 " , " WGOR " , - 3 ) ;
st . update_well_var ( " P1 " , " WWIR " , 4 ) ;
2019-03-07 03:54:56 -06:00
2019-05-12 03:01:26 -05:00
st . update_well_var ( " P2 " , " WOPR " , 0 ) ;
st . update_well_var ( " P2 " , " WWPR " , - 2 ) ;
st . update_well_var ( " P2 " , " WGOR " , 4 ) ;
st . update_well_var ( " P2 " , " WWIR " , 1 ) ;
2019-03-07 03:54:56 -06:00
2019-05-24 08:50:40 -05:00
auto res_cmp = def_cmp . eval ( context ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( res_cmp [ " P1 " ] . get ( ) , 1.0 ) ;
BOOST_CHECK_EQUAL ( res_cmp [ " P2 " ] . get ( ) , 0.0 ) ;
2019-03-07 03:54:56 -06:00
}
2023-01-11 04:23:40 -06:00
#if 0
BOOST_AUTO_TEST_CASE ( UDQPARSE_ERROR ) {
2019-03-11 05:43:23 -05:00
setUDQFunctionTable udqft ;
UDQDefine def1 ( udqft , " WUBHP " , { " WWCT " , " + " } ) ;
}
2023-01-11 04:23:40 -06:00
# endif
2019-03-11 05:43:23 -05:00
2019-06-13 09:40:12 -05:00
BOOST_AUTO_TEST_CASE ( UDQ_SCALAR_SET ) {
2020-09-27 15:13:30 -05:00
KeywordLocation location ;
2019-06-13 09:40:12 -05:00
UDQParams udqp ;
UDQFunctionTable udqft ;
2021-02-28 10:04:35 -06:00
SummaryState st ( TimeService : : now ( ) ) ;
2020-08-31 00:38:52 -05:00
UDQState udq_state ( udqp . undefinedValue ( ) ) ;
2023-01-10 03:44:15 -06:00
WellMatcher wm ( NameOrder ( { " PA1 " , " PB2 " , " PC3 " , " PD4 " } ) ) ;
2023-01-19 06:20:52 -06:00
auto segmentMatcherFactory = [ ] ( ) { return std : : make_unique < SegmentMatcher > ( ScheduleState { } ) ; } ;
2023-10-23 08:07:23 -05:00
UDQContext context ( udqft , wm , { } , segmentMatcherFactory , st , udq_state ) ;
2019-06-13 09:40:12 -05:00
2020-10-30 07:36:41 -05:00
st . update_well_var ( " PA1 " , " WOPR " , 1 ) ;
st . update_well_var ( " PB2 " , " WOPR " , 2 ) ;
st . update_well_var ( " PC3 " , " WOPR " , 3 ) ;
st . update_well_var ( " PD4 " , " WOPR " , 4 ) ;
2019-06-13 09:40:12 -05:00
2020-10-30 07:36:41 -05:00
st . update_well_var ( " PA1 " , " WWPR " , 1 ) ;
st . update_well_var ( " PB2 " , " WWPR " , 2 ) ;
st . update_well_var ( " PC3 " , " WWPR " , 3 ) ;
st . update_well_var ( " PD4 " , " WWPR " , 4 ) ;
2019-06-13 09:40:12 -05:00
{
2020-11-15 03:03:34 -06:00
UDQDefine def ( udqp , " WUOPR " , 0 , location , { " WOPR " , " 'PA*' " } ) ;
2019-06-13 09:40:12 -05:00
auto res = def . eval ( context ) ;
2020-09-29 06:54:21 -05:00
BOOST_CHECK_EQUAL ( 4U , res . size ( ) ) ;
2020-10-30 07:36:41 -05:00
auto well1 = res [ " PA1 " ] ;
2019-06-13 09:40:12 -05:00
BOOST_CHECK ( well1 . defined ( ) ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( well1 . get ( ) , 1 ) ;
2019-06-13 09:40:12 -05:00
2020-10-30 07:36:41 -05:00
auto well2 = res [ " PB2 " ] ;
2019-06-13 09:40:12 -05:00
BOOST_CHECK ( ! well2 . defined ( ) ) ;
2020-10-30 07:36:41 -05:00
auto well4 = res [ " PD4 " ] ;
2019-06-13 09:40:12 -05:00
BOOST_CHECK ( ! well4 . defined ( ) ) ;
}
{
2020-11-15 03:03:34 -06:00
UDQDefine def ( udqp , " WUOPR " , 0 , location , { " 1 " } ) ;
2019-06-13 09:40:12 -05:00
auto res = def . eval ( context ) ;
2020-09-29 06:54:21 -05:00
BOOST_CHECK_EQUAL ( 4U , res . size ( ) ) ;
2020-10-30 07:36:41 -05:00
auto well1 = res [ " PA1 " ] ;
2019-06-13 09:40:12 -05:00
BOOST_CHECK ( well1 . defined ( ) ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( well1 . get ( ) , 1 ) ;
2019-06-13 09:40:12 -05:00
2020-10-30 07:36:41 -05:00
auto well2 = res [ " PB2 " ] ;
2019-06-13 09:40:12 -05:00
BOOST_CHECK ( well2 . defined ( ) ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( well2 . get ( ) , 1 ) ;
2019-06-13 09:40:12 -05:00
2020-10-30 07:36:41 -05:00
auto well4 = res [ " PD4 " ] ;
2019-06-13 09:40:12 -05:00
BOOST_CHECK ( well4 . defined ( ) ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( well4 . get ( ) , 1 ) ;
2019-06-13 09:40:12 -05:00
}
{
2020-11-15 03:03:34 -06:00
UDQDefine def ( udqp , " WUOPR " , 0 , location , { " WOPR " , " 'PA1' " } ) ;
2019-06-13 09:40:12 -05:00
auto res = def . eval ( context ) ;
2020-09-29 06:54:21 -05:00
BOOST_CHECK_EQUAL ( 4U , res . size ( ) ) ;
2020-10-30 07:36:41 -05:00
auto well1 = res [ " PA1 " ] ;
2019-06-13 09:40:12 -05:00
BOOST_CHECK ( well1 . defined ( ) ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( well1 . get ( ) , 1 ) ;
2019-06-13 09:40:12 -05:00
2020-10-30 07:36:41 -05:00
auto well2 = res [ " PB2 " ] ;
2019-06-13 09:40:12 -05:00
BOOST_CHECK ( well2 . defined ( ) ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( well2 . get ( ) , 1 ) ;
2019-06-13 09:40:12 -05:00
2020-10-30 07:36:41 -05:00
auto well4 = res [ " PD4 " ] ;
2019-06-13 09:40:12 -05:00
BOOST_CHECK ( well4 . defined ( ) ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( well4 . get ( ) , 1 ) ;
2020-06-11 07:22:49 -05:00
BOOST_CHECK_EQUAL ( " WUOPR " , res . name ( ) ) ;
2019-06-13 09:40:12 -05:00
}
}
2020-06-11 06:41:02 -05:00
BOOST_AUTO_TEST_CASE ( UDQ_SORTD_NAN ) {
UDQParams udqp ;
UDQFunctionTable udqft ;
2020-09-27 15:13:30 -05:00
KeywordLocation location ;
2020-11-15 03:03:34 -06:00
UDQDefine def ( udqp , " WUPR1 " , 0 , location , { " 1 " , " / " , " ( " , " WWIR " , " 'OP*' " , " ) " }) ;
UDQDefine def_sort ( udqp , " WUPR3 " , 0 , location , { " SORTD " , " ( " , " WUPR1 " , " ) " }) ;
2021-02-28 10:04:35 -06:00
SummaryState st ( TimeService : : now ( ) ) ;
2020-08-31 00:38:52 -05:00
UDQState udq_state ( udqp . undefinedValue ( ) ) ;
2023-01-10 03:44:15 -06:00
WellMatcher wm ( NameOrder ( { " OP1 " , " OP2 " , " OP3 " , " OP4 " } ) ) ;
2023-01-19 06:20:52 -06:00
auto segmentMatcherFactory = [ ] ( ) { return std : : make_unique < SegmentMatcher > ( ScheduleState { } ) ; } ;
2023-10-23 08:07:23 -05:00
UDQContext context ( udqft , wm , { } , segmentMatcherFactory , st , udq_state ) ;
2020-06-11 06:41:02 -05:00
st . update_well_var ( " OP1 " , " WWIR " , 1.0 ) ;
st . update_well_var ( " OP2 " , " WWIR " , 2.0 ) ;
st . update_well_var ( " OP3 " , " WWIR " , 3.0 ) ;
st . update_well_var ( " OP4 " , " WWIR " , 4.0 ) ;
2020-06-11 08:19:47 -05:00
auto res1 = def . eval ( context ) ;
2020-11-15 03:03:34 -06:00
context . update_define ( 0 , def . keyword ( ) , res1 ) ;
2020-06-11 06:41:02 -05:00
2020-06-11 08:19:47 -05:00
auto res_sort1 = def_sort . eval ( context ) ;
2020-11-15 03:03:34 -06:00
context . update_define ( 0 , def_sort . keyword ( ) , res_sort1 ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( res_sort1 [ " OP1 " ] . get ( ) , 1.0 ) ;
BOOST_CHECK_EQUAL ( res_sort1 [ " OP2 " ] . get ( ) , 2.0 ) ;
BOOST_CHECK_EQUAL ( res_sort1 [ " OP3 " ] . get ( ) , 3.0 ) ;
BOOST_CHECK_EQUAL ( res_sort1 [ " OP4 " ] . get ( ) , 4.0 ) ;
2020-06-11 08:19:47 -05:00
BOOST_CHECK ( st . has_well_var ( " OP1 " , " WUPR3 " ) ) ;
BOOST_CHECK ( st . has_well_var ( " OP4 " , " WUPR3 " ) ) ;
st . update_well_var ( " OP1 " , " WWIR " , 0 ) ;
auto res2 = def . eval ( context ) ;
2020-09-29 06:54:21 -05:00
BOOST_CHECK_EQUAL ( res2 . defined_size ( ) , 3U ) ;
2020-10-20 13:46:43 -05:00
2020-11-15 03:03:34 -06:00
context . update_define ( 0 , def . keyword ( ) , res2 ) ;
2020-06-11 08:19:47 -05:00
BOOST_CHECK ( st . has_well_var ( " OP4 " , " WUPR1 " ) ) ;
auto res_sort2 = def_sort . eval ( context ) ;
2020-11-15 03:03:34 -06:00
context . update_define ( 0 , def . keyword ( ) , res2 ) ;
2020-10-20 13:46:43 -05:00
2020-09-29 06:54:21 -05:00
BOOST_CHECK_EQUAL ( res_sort2 . defined_size ( ) , 3U ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( res_sort2 [ " OP2 " ] . get ( ) , 1.0 ) ;
BOOST_CHECK_EQUAL ( res_sort2 [ " OP3 " ] . get ( ) , 2.0 ) ;
BOOST_CHECK_EQUAL ( res_sort2 [ " OP4 " ] . get ( ) , 3.0 ) ;
2020-06-11 08:19:47 -05:00
BOOST_CHECK ( st . has_well_var ( " OP4 " , " WUPR3 " ) ) ;
2020-06-11 06:41:02 -05:00
}
2019-12-23 05:19:51 -06:00
BOOST_AUTO_TEST_CASE ( UDQ_SORTA ) {
2020-09-27 15:13:30 -05:00
KeywordLocation location ;
2019-12-23 05:19:51 -06:00
UDQParams udqp ;
UDQFunctionTable udqft ;
2020-11-15 03:03:34 -06:00
UDQDefine def1 ( udqp , " WUPR1 " , 0 , location , { " 1 " , " / " , " ( " , " WWCT " , " 'OP*' " , " + " , " 0.00001 " , " ) " }) ;
UDQDefine def_sort ( udqp , " WUPR3 " , 0 , location , { " SORTA " , " ( " , " WUPR1 " , " ) " }) ;
2021-02-28 10:04:35 -06:00
SummaryState st ( TimeService : : now ( ) ) ;
2020-08-31 00:38:52 -05:00
UDQState udq_state ( udqp . undefinedValue ( ) ) ;
2023-01-10 03:44:15 -06:00
WellMatcher wm ( NameOrder ( { " OPL01 " , " OPL02 " , " OPU01 " , " OPU02 " } ) ) ;
2023-01-19 06:20:52 -06:00
auto segmentMatcherFactory = [ ] ( ) { return std : : make_unique < SegmentMatcher > ( ScheduleState { } ) ; } ;
2023-10-23 08:07:23 -05:00
UDQContext context ( udqft , wm , { } , segmentMatcherFactory , st , udq_state ) ;
2019-12-23 05:19:51 -06:00
st . update_well_var ( " OPL01 " , " WWCT " , 0.7 ) ;
st . update_well_var ( " OPL02 " , " WWCT " , 0.8 ) ;
st . update_well_var ( " OPU01 " , " WWCT " , 0.0 ) ;
st . update_well_var ( " OPU02 " , " WWCT " , 0.0 ) ;
auto res1 = def1 . eval ( context ) ;
2020-11-15 03:03:34 -06:00
context . update_define ( 0 , def1 . keyword ( ) , res1 ) ;
2019-12-23 05:19:51 -06:00
auto res_sort = def_sort . eval ( context ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( res_sort [ " OPL02 " ] . get ( ) , 1.0 ) ;
BOOST_CHECK_EQUAL ( res_sort [ " OPL01 " ] . get ( ) , 2.0 ) ;
BOOST_CHECK_EQUAL ( res_sort [ " OPU01 " ] . get ( ) + res_sort [ " OPU02 " ] . get ( ) , 7.0 ) ;
2019-12-23 05:19:51 -06:00
}
2019-03-07 03:54:56 -06:00
BOOST_AUTO_TEST_CASE ( UDQ_BASIC_MATH_TEST ) {
2019-03-11 05:43:23 -05:00
UDQParams udqp ;
2019-03-07 03:54:56 -06:00
UDQFunctionTable udqft ;
2020-09-27 15:13:30 -05:00
KeywordLocation location ;
2020-11-15 03:03:34 -06:00
UDQDefine def_add ( udqp , " WU2OPR " , 0 , location , { " WOPR " , " + " , " WOPR " } ) ;
UDQDefine def_sub ( udqp , " WU2OPR " , 0 , location , { " WOPR " , " - " , " WOPR " } ) ;
UDQDefine def_mul ( udqp , " WU2OPR " , 0 , location , { " WOPR " , " * " , " WOPR " } ) ;
UDQDefine def_div ( udqp , " WU2OPR " , 0 , location , { " WOPR " , " / " , " WOPR " } ) ;
UDQDefine def_muladd ( udqp , " WUX " , 0 , location , { " WOPR " , " + " , " WOPR " , " * " , " WOPR " } ) ;
UDQDefine def_wuwct ( udqp , " WUWCT " , 0 , location , { " WWPR " , " / " , " ( " , " WOPR " , " + " , " WWPR " , " ) " }) ;
2021-02-28 10:04:35 -06:00
SummaryState st ( TimeService : : now ( ) ) ;
2020-08-31 00:38:52 -05:00
UDQState udq_state ( udqp . undefinedValue ( ) ) ;
2023-01-10 03:44:15 -06:00
WellMatcher wm ( NameOrder ( { " P1 " , " P2 " , " P3 " , " P4 " } ) ) ;
2023-01-19 06:20:52 -06:00
auto segmentMatcherFactory = [ ] ( ) { return std : : make_unique < SegmentMatcher > ( ScheduleState { } ) ; } ;
2023-10-23 08:07:23 -05:00
UDQContext context ( udqft , wm , { } , segmentMatcherFactory , st , udq_state ) ;
2019-03-07 03:54:56 -06:00
2019-05-12 03:01:26 -05:00
st . update_well_var ( " P1 " , " WOPR " , 1 ) ;
st . update_well_var ( " P2 " , " WOPR " , 2 ) ;
st . update_well_var ( " P3 " , " WOPR " , 3 ) ;
st . update_well_var ( " P4 " , " WOPR " , 4 ) ;
2019-03-07 03:54:56 -06:00
2019-05-12 03:01:26 -05:00
st . update_well_var ( " P1 " , " WWPR " , 1 ) ;
st . update_well_var ( " P2 " , " WWPR " , 2 ) ;
st . update_well_var ( " P3 " , " WWPR " , 3 ) ;
st . update_well_var ( " P4 " , " WWPR " , 4 ) ;
2019-03-07 03:54:56 -06:00
2019-05-24 08:50:40 -05:00
auto res_add = def_add . eval ( context ) ;
2020-09-29 06:54:21 -05:00
BOOST_CHECK_EQUAL ( res_add . size ( ) , 4U ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( res_add [ " P1 " ] . get ( ) , 2 ) ;
BOOST_CHECK_EQUAL ( res_add [ " P2 " ] . get ( ) , 4 ) ;
BOOST_CHECK_EQUAL ( res_add [ " P3 " ] . get ( ) , 6 ) ;
BOOST_CHECK_EQUAL ( res_add [ " P4 " ] . get ( ) , 8 ) ;
2019-03-07 03:54:56 -06:00
2019-05-24 08:50:40 -05:00
auto res_sub = def_sub . eval ( context ) ;
2020-09-29 06:54:21 -05:00
BOOST_CHECK_EQUAL ( res_sub . size ( ) , 4U ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( res_sub [ " P1 " ] . get ( ) , 0 ) ;
BOOST_CHECK_EQUAL ( res_sub [ " P2 " ] . get ( ) , 0 ) ;
BOOST_CHECK_EQUAL ( res_sub [ " P3 " ] . get ( ) , 0 ) ;
BOOST_CHECK_EQUAL ( res_sub [ " P4 " ] . get ( ) , 0 ) ;
2019-03-07 03:54:56 -06:00
2019-05-24 08:50:40 -05:00
auto res_div = def_div . eval ( context ) ;
2020-09-29 06:54:21 -05:00
BOOST_CHECK_EQUAL ( res_div . size ( ) , 4U ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( res_div [ " P1 " ] . get ( ) , 1 ) ;
BOOST_CHECK_EQUAL ( res_div [ " P2 " ] . get ( ) , 1 ) ;
BOOST_CHECK_EQUAL ( res_div [ " P3 " ] . get ( ) , 1 ) ;
BOOST_CHECK_EQUAL ( res_div [ " P4 " ] . get ( ) , 1 ) ;
2019-03-07 03:54:56 -06:00
2019-05-24 08:50:40 -05:00
auto res_mul = def_mul . eval ( context ) ;
2020-09-29 06:54:21 -05:00
BOOST_CHECK_EQUAL ( res_mul . size ( ) , 4U ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( res_mul [ " P1 " ] . get ( ) , 1 ) ;
BOOST_CHECK_EQUAL ( res_mul [ " P2 " ] . get ( ) , 4 ) ;
BOOST_CHECK_EQUAL ( res_mul [ " P3 " ] . get ( ) , 9 ) ;
BOOST_CHECK_EQUAL ( res_mul [ " P4 " ] . get ( ) , 16 ) ;
2019-03-07 03:54:56 -06:00
2019-05-24 08:50:40 -05:00
auto res_muladd = def_muladd . eval ( context ) ;
2020-09-29 06:54:21 -05:00
BOOST_CHECK_EQUAL ( res_muladd . size ( ) , 4U ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( res_muladd [ " P1 " ] . get ( ) , 1 + 1 ) ;
BOOST_CHECK_EQUAL ( res_muladd [ " P2 " ] . get ( ) , 4 + 2 ) ;
BOOST_CHECK_EQUAL ( res_muladd [ " P3 " ] . get ( ) , 9 + 3 ) ;
BOOST_CHECK_EQUAL ( res_muladd [ " P4 " ] . get ( ) , 16 + 4 ) ;
2019-03-07 03:54:56 -06:00
2019-05-24 08:50:40 -05:00
auto res_wuwct = def_wuwct . eval ( context ) ;
2020-09-29 06:54:21 -05:00
BOOST_CHECK_EQUAL ( res_wuwct . size ( ) , 4U ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( res_wuwct [ " P1 " ] . get ( ) , 0.50 ) ;
BOOST_CHECK_EQUAL ( res_wuwct [ " P2 " ] . get ( ) , 0.50 ) ;
BOOST_CHECK_EQUAL ( res_wuwct [ " P3 " ] . get ( ) , 0.50 ) ;
BOOST_CHECK_EQUAL ( res_wuwct [ " P4 " ] . get ( ) , 0.50 ) ;
2019-03-07 03:54:56 -06:00
}
2019-06-16 01:40:06 -05:00
BOOST_AUTO_TEST_CASE ( DECK_TEST ) {
2020-09-27 15:13:30 -05:00
KeywordLocation location ;
2019-06-16 01:40:06 -05:00
UDQParams udqp ;
UDQFunctionTable udqft ( udqp ) ;
2020-11-15 03:03:34 -06:00
UDQDefine def ( udqp , " WUOPRL " , 0 , location , { " ( " , " WOPR " , " OP1 " , " - " , " 150 " , " ) " , " * " , " 0.90 " }) ;
2021-02-28 10:04:35 -06:00
SummaryState st ( TimeService : : now ( ) ) ;
2020-08-31 00:38:52 -05:00
UDQState udq_state ( udqp . undefinedValue ( ) ) ;
2023-01-10 03:44:15 -06:00
WellMatcher wm ( NameOrder ( { " OP1 " , " OP2 " , " OP3 " } ) ) ;
2023-01-19 06:20:52 -06:00
auto segmentMatcherFactory = [ ] ( ) { return std : : make_unique < SegmentMatcher > ( ScheduleState { } ) ; } ;
2023-10-23 08:07:23 -05:00
UDQContext context ( udqft , wm , { } , segmentMatcherFactory , st , udq_state ) ;
2019-06-16 01:40:06 -05:00
st . update_well_var ( " OP1 " , " WOPR " , 300 ) ;
st . update_well_var ( " OP2 " , " WOPR " , 3000 ) ;
st . update_well_var ( " OP3 " , " WOPR " , 30000 ) ;
auto res = def . eval ( context ) ;
2020-09-29 06:54:21 -05:00
BOOST_CHECK_EQUAL ( res . size ( ) , 3U ) ;
2019-06-16 01:40:06 -05:00
for ( std : : size_t index = 0 ; index < res . size ( ) ; index + + )
2020-08-31 00:38:52 -05:00
BOOST_CHECK ( res [ index ] . get ( ) = = ( 300 - 150 ) * 0.90 ) ;
2019-06-16 01:40:06 -05:00
}
2019-03-07 03:54:56 -06:00
BOOST_AUTO_TEST_CASE ( UDQPARSE_TEST1 ) {
2020-09-27 15:13:30 -05:00
KeywordLocation location ;
2019-03-11 05:43:23 -05:00
UDQParams udqp ;
2020-11-15 03:03:34 -06:00
UDQDefine def1 ( udqp , " WUBHP " , 0 , location , { " 1/(WWCT " , " 'W1*') " }) ;
2021-07-25 09:24:47 -05:00
BOOST_CHECK_EQUAL ( def1 . input_string ( ) , " 1 / (WWCT 'W1*') " ) ;
2019-06-24 07:36:44 -05:00
2021-07-25 09:24:47 -05:00
UDQDefine def2 ( udqp , " WUBHP " , 0 , location , { " 2 * (1 " , " + " , " WBHP) " }) ;
BOOST_CHECK_EQUAL ( def2 . input_string ( ) , " 2 * (1 + WBHP) " ) ;
2019-03-07 03:54:56 -06:00
}
2022-03-11 02:48:52 -06:00
BOOST_AUTO_TEST_CASE ( INPUT_STRING_SCIENTIFIC_NOTATION ) {
const auto schedule = make_schedule ( R " (
SCHEDULE
UDQ
DEFINE FU_THREE ( 3000000 + FU_ONE * 1500000 + 1000000 * FU_TWO ) / 365 /
/
) " );
const auto & udq = schedule . getUDQConfig ( 0 ) ;
const auto def = udq . definitions ( ) ;
BOOST_CHECK_EQUAL ( def . size ( ) , 1ULL ) ;
const auto expect_input_string = std : : string {
" (3E+06 + FU_ONE * 1.5E+06 + 1E+06 * FU_TWO) / 365 "
} ;
BOOST_CHECK_EQUAL ( def [ 0 ] . input_string ( ) , expect_input_string ) ;
}
2019-03-11 05:43:23 -05:00
2019-05-24 08:50:40 -05:00
BOOST_AUTO_TEST_CASE ( UDQ_PARSE_ERROR ) {
2019-03-11 05:43:23 -05:00
UDQParams udqp ;
ParseContext parseContext ;
ErrorGuard errors ;
std : : vector < std : : string > tokens = { " WBHP " , " + " } ;
2020-09-27 15:13:30 -05:00
KeywordLocation location ;
2023-01-11 06:18:25 -06:00
parseContext . update ( ParseContext : : UDQ_PARSE_ERROR , InputErrorAction : : IGNORE ) ;
2019-03-11 05:43:23 -05:00
{
2020-11-15 03:03:34 -06:00
UDQDefine def1 ( udqp , " WUBHP " , 0 , location , tokens , parseContext , errors ) ;
2021-02-28 10:04:35 -06:00
SummaryState st ( TimeService : : now ( ) ) ;
2019-06-13 09:40:12 -05:00
UDQFunctionTable udqft ( udqp ) ;
2020-08-31 00:38:52 -05:00
UDQState udq_state ( udqp . undefinedValue ( ) ) ;
2023-01-10 03:44:15 -06:00
WellMatcher wm ( NameOrder ( { " P1 " } ) ) ;
2023-01-19 06:20:52 -06:00
auto segmentMatcherFactory = [ ] ( ) { return std : : make_unique < SegmentMatcher > ( ScheduleState { } ) ; } ;
2023-10-23 08:07:23 -05:00
UDQContext context ( udqft , wm , { } , segmentMatcherFactory , st , udq_state ) ;
2019-05-27 02:44:14 -05:00
st . update_well_var ( " P1 " , " WBHP " , 1 ) ;
2019-03-11 05:43:23 -05:00
2019-05-24 08:50:40 -05:00
auto res = def1 . eval ( context ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( res [ " P1 " ] . get ( ) , udqp . undefinedValue ( ) ) ;
2019-03-11 05:43:23 -05:00
}
2023-01-11 06:18:25 -06:00
parseContext . update ( ParseContext : : UDQ_PARSE_ERROR , InputErrorAction : : THROW_EXCEPTION ) ;
2020-11-15 03:03:34 -06:00
BOOST_CHECK_THROW ( UDQDefine ( udqp , " WUBHP " , 0 , location , tokens , parseContext , errors ) , OpmInputError ) ;
2019-03-11 05:43:23 -05:00
}
2019-04-13 02:09:57 -05:00
2019-05-24 08:50:40 -05:00
BOOST_AUTO_TEST_CASE ( UDQ_TYPE_ERROR ) {
UDQParams udqp ;
ParseContext parseContext ;
ErrorGuard errors ;
std : : vector < std : : string > tokens1 = { " WBHP " , " + " , " 1 " } ;
std : : vector < std : : string > tokens2 = { " SUM " , " ( " , " WBHP " , " ) " } ;
2020-09-27 15:13:30 -05:00
KeywordLocation location ;
2023-01-11 06:18:25 -06:00
parseContext . update ( ParseContext : : UDQ_TYPE_ERROR , InputErrorAction : : IGNORE ) ;
2019-05-24 08:50:40 -05:00
{
2020-11-15 03:03:34 -06:00
UDQDefine def1 ( udqp , " FUBHP " , 0 , location , tokens1 , parseContext , errors ) ;
UDQDefine def2 ( udqp , " WUBHP " , 0 , location , tokens2 , parseContext , errors ) ;
2019-05-24 08:50:40 -05:00
2021-02-28 10:04:35 -06:00
SummaryState st ( TimeService : : now ( ) ) ;
2019-06-13 09:40:12 -05:00
UDQFunctionTable udqft ( udqp ) ;
2020-08-31 00:38:52 -05:00
UDQState udq_state ( udqp . undefinedValue ( ) ) ;
2023-01-10 03:44:15 -06:00
WellMatcher wm ( NameOrder ( { " P1 " , " P2 " } ) ) ;
2023-01-19 06:20:52 -06:00
auto segmentMatcherFactory = [ ] ( ) { return std : : make_unique < SegmentMatcher > ( ScheduleState { } ) ; } ;
2023-10-23 08:07:23 -05:00
UDQContext context ( udqft , wm , { } , segmentMatcherFactory , st , udq_state ) ;
2019-05-24 08:50:40 -05:00
st . update_well_var ( " P1 " , " WBHP " , 1 ) ;
2019-06-13 09:40:12 -05:00
st . update_well_var ( " P2 " , " WBHP " , 2 ) ;
2019-05-24 08:50:40 -05:00
auto res1 = def1 . eval ( context ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( res1 [ 0 ] . get ( ) , udqp . undefinedValue ( ) ) ;
2019-05-24 08:50:40 -05:00
auto res2 = def2 . eval ( context ) ;
BOOST_CHECK_EQUAL ( res2 . size ( ) , st . num_wells ( ) ) ;
for ( std : : size_t index = 0 ; index < res2 . size ( ) ; index + + )
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( res2 [ index ] . get ( ) , 3 ) ;
2019-05-24 08:50:40 -05:00
}
2023-01-11 06:18:25 -06:00
parseContext . update ( ParseContext : : UDQ_TYPE_ERROR , InputErrorAction : : THROW_EXCEPTION ) ;
2019-05-24 08:50:40 -05:00
// This fails because the well expression (WBHP + 1) is assigned to the field variable FUBHP
2020-11-15 03:03:34 -06:00
BOOST_CHECK_THROW ( UDQDefine ( udqp , " FUBHP " , 0 , location , tokens1 , parseContext , errors ) , OpmInputError ) ;
2019-05-24 08:50:40 -05:00
}
2019-04-13 02:09:57 -05:00
BOOST_AUTO_TEST_CASE ( UDA_VALUE ) {
UDAValue value0 ;
BOOST_CHECK ( value0 . is < double > ( ) ) ;
BOOST_CHECK ( ! value0 . is < std : : string > ( ) ) ;
BOOST_CHECK_EQUAL ( value0 . get < double > ( ) , 0 ) ;
BOOST_CHECK_THROW ( value0 . get < std : : string > ( ) , std : : invalid_argument ) ;
2020-10-29 09:52:26 -05:00
value0 . update ( 10 ) ;
2019-06-07 03:17:57 -05:00
BOOST_CHECK_EQUAL ( value0 . get < double > ( ) , 10 ) ;
BOOST_CHECK_THROW ( value0 . get < std : : string > ( ) , std : : invalid_argument ) ;
2020-10-29 09:52:26 -05:00
value0 . update ( " STRING " ) ;
2019-06-07 03:17:57 -05:00
BOOST_CHECK_EQUAL ( value0 . get < std : : string > ( ) , std : : string ( " STRING " ) ) ;
BOOST_CHECK_THROW ( value0 . get < double > ( ) , std : : invalid_argument ) ;
2019-04-13 02:09:57 -05:00
UDAValue value1 ( 10 ) ;
BOOST_CHECK ( value1 . is < double > ( ) ) ;
BOOST_CHECK ( ! value1 . is < std : : string > ( ) ) ;
BOOST_CHECK_EQUAL ( value1 . get < double > ( ) , 10 ) ;
2019-06-23 02:07:07 -05:00
BOOST_CHECK_NO_THROW ( value1 . assert_numeric ( ) ) ;
2021-10-19 04:12:06 -05:00
value1 * = 10 ;
BOOST_CHECK_EQUAL ( value1 . get < double > ( ) , 100 ) ;
2019-04-13 02:09:57 -05:00
UDAValue value2 ( " FUBHP " ) ;
BOOST_CHECK ( ! value2 . is < double > ( ) ) ;
BOOST_CHECK ( value2 . is < std : : string > ( ) ) ;
BOOST_CHECK_EQUAL ( value2 . get < std : : string > ( ) , std : : string ( " FUBHP " ) ) ;
BOOST_CHECK_THROW ( value2 . get < double > ( ) , std : : invalid_argument ) ;
2019-06-23 02:07:07 -05:00
BOOST_CHECK_THROW ( value2 . assert_numeric ( " SHould contain numeric value " ) , std : : invalid_argument ) ;
2021-10-19 04:12:06 -05:00
BOOST_CHECK_THROW ( value2 * = 10 , std : : exception ) ;
2019-04-13 02:09:57 -05:00
}
2019-06-07 03:17:29 -05:00
2023-01-11 04:23:40 -06:00
// The unit/dimension handling in the UDAvalue is hacky at best.
2019-06-07 03:17:29 -05:00
BOOST_AUTO_TEST_CASE ( UDA_VALUE_DIM ) {
UDAValue value0 ( 1 ) ;
2020-03-04 13:45:56 -06:00
Dimension dim ( 10 ) ;
2020-03-05 03:04:24 -06:00
UDAValue value1 ( 1 , dim ) ;
2019-09-16 01:12:13 -05:00
2019-06-07 03:17:29 -05:00
BOOST_CHECK_EQUAL ( value0 . get < double > ( ) , 1 ) ;
2020-01-03 05:58:55 -06:00
BOOST_CHECK_EQUAL ( value0 . getSI ( ) , 1 ) ;
BOOST_CHECK_EQUAL ( value1 . get < double > ( ) , 1 ) ;
BOOST_CHECK_EQUAL ( value1 . getSI ( ) , 10 ) ;
2019-06-07 03:17:29 -05:00
}
2019-06-24 09:04:48 -05:00
BOOST_AUTO_TEST_CASE ( UDQ_INPUT_BASIC ) {
std : : string deck_string = R " (
SCHEDULE
UDQ
2020-04-12 01:38:59 -05:00
ASSIGN WUBHP1 11 / 0
ASSIGN WUOPR 20 / 1
ASSIGN WUBHP2 P2 12 / 2
2019-06-24 09:04:48 -05:00
UNITS WUBHP ' BARSA ' /
UNITS WUOPR ' SM3 / DAY ' /
2021-09-09 01:24:10 -05:00
DEFINE WUWCT WWPR / ( WWPR + WOPR ) / 3
2019-06-24 09:04:48 -05:00
UNITS WUWCT ' 1 ' /
2021-09-09 01:24:10 -05:00
DEFINE FUOPR SUM ( WOPR ) / 4
2019-06-24 09:04:48 -05:00
UNITS FUOPR ' SM3 / DAY ' /
UNITS FUXXX ' SM3 / DAY ' /
/
UDQ
2021-09-09 01:24:10 -05:00
ASSIGN WUBHPX P2 12 / 5
DEFINE FUOPRX SUM ( WOPR ) / 6
2019-06-24 09:04:48 -05:00
/
) " ;
auto schedule = make_schedule ( deck_string ) ;
const auto & udq = schedule . getUDQConfig ( 0 ) ;
2019-07-26 10:56:50 -05:00
const auto & input = udq . input ( ) ;
2019-06-24 09:04:48 -05:00
const auto & def = udq . definitions ( ) ;
2021-09-09 01:24:10 -05:00
BOOST_CHECK_EQUAL ( input . size ( ) , 7U ) ;
BOOST_CHECK_EQUAL ( udq . size ( ) , 7U ) ;
2019-06-24 09:04:48 -05:00
2019-07-26 10:56:50 -05:00
BOOST_CHECK ( input [ 0 ] . is < UDQAssign > ( ) ) ;
BOOST_CHECK ( input [ 1 ] . is < UDQAssign > ( ) ) ;
BOOST_CHECK ( input [ 2 ] . is < UDQAssign > ( ) ) ;
2021-09-09 01:24:10 -05:00
BOOST_CHECK ( input [ 3 ] . is < UDQDefine > ( ) ) ;
2019-07-26 10:56:50 -05:00
BOOST_CHECK ( input [ 4 ] . is < UDQDefine > ( ) ) ;
2021-09-09 01:24:10 -05:00
BOOST_CHECK ( input [ 5 ] . is < UDQAssign > ( ) ) ;
BOOST_CHECK ( input [ 6 ] . is < UDQDefine > ( ) ) ;
2019-06-24 09:04:48 -05:00
2021-09-09 01:24:10 -05:00
BOOST_CHECK_EQUAL ( input [ 1 ] . unit ( ) , " SM3/DAY " ) ;
2019-06-24 09:04:48 -05:00
BOOST_CHECK_EQUAL ( def [ 0 ] . keyword ( ) , " WUWCT " ) ;
BOOST_CHECK_EQUAL ( def [ 1 ] . keyword ( ) , " FUOPR " ) ;
BOOST_CHECK_EQUAL ( def [ 2 ] . keyword ( ) , " FUOPRX " ) ;
2021-09-09 01:24:10 -05:00
BOOST_CHECK_EQUAL ( input [ 3 ] . get < UDQDefine > ( ) . keyword ( ) , " WUWCT " ) ;
BOOST_CHECK_EQUAL ( input [ 4 ] . get < UDQDefine > ( ) . keyword ( ) , " FUOPR " ) ;
BOOST_CHECK_EQUAL ( input [ 6 ] . get < UDQDefine > ( ) . keyword ( ) , " FUOPRX " ) ;
2019-07-26 10:56:50 -05:00
2021-09-09 01:26:41 -05:00
BOOST_CHECK ( ! udq . has_keyword ( " FUXXX " ) ) ;
2019-07-29 03:50:28 -05:00
const auto wubhp1 = udq [ " WUBHP1 " ] ;
BOOST_CHECK ( wubhp1 . is < UDQAssign > ( ) ) ;
2019-06-24 09:04:48 -05:00
}
BOOST_AUTO_TEST_CASE ( UDQ_INPUT_OVERWRITE ) {
std : : string deck_string = R " (
SCHEDULE
UDQ
ASSIGN WUBHP1 11 /
ASSIGN WUOPR 20 /
ASSIGN WUBHP2 P2 12 /
2020-04-12 01:38:59 -05:00
- - ASSIGN WUBHP 0 / - - DUMMY
2019-06-24 09:04:48 -05:00
UNITS WUBHP ' BARSA ' /
UNITS WUOPR ' SM3 / DAY ' /
DEFINE WUWCT WWPR / ( WWPR + WOPR ) /
UNITS WUWCT ' 1 ' /
DEFINE FUOPR SUM ( WOPR ) /
UNITS FUOPR ' SM3 / DAY ' /
/
UDQ
DEFINE WUBHP1 SUM ( WOPR ) /
2019-07-30 07:54:45 -05:00
DEFINE FUOPR MAX ( WOPR ) /
2019-06-24 09:04:48 -05:00
/
) " ;
auto schedule = make_schedule ( deck_string ) ;
const auto & udq = schedule . getUDQConfig ( 0 ) ;
2019-07-26 10:56:50 -05:00
const auto & input = udq . input ( ) ;
2021-09-09 01:24:10 -05:00
BOOST_CHECK_EQUAL ( input . size ( ) , 5U ) ;
BOOST_CHECK_EQUAL ( udq . size ( ) , 5U ) ;
2019-06-24 09:04:48 -05:00
2019-07-26 10:56:50 -05:00
BOOST_CHECK ( input [ 0 ] . is < UDQDefine > ( ) ) ;
2019-07-29 03:50:28 -05:00
BOOST_CHECK_EQUAL ( input [ 0 ] . keyword ( ) , " WUBHP1 " ) ;
2019-07-30 07:54:45 -05:00
const auto fuopr = udq [ " FUOPR " ] ;
BOOST_CHECK ( fuopr . is < UDQDefine > ( ) ) ;
const auto & def2 = fuopr . get < UDQDefine > ( ) ;
BOOST_CHECK_EQUAL ( def2 . input_string ( ) , " MAX(WOPR) " ) ;
2019-07-26 10:17:06 -05:00
}
BOOST_AUTO_TEST_CASE ( UDQ_USAGE ) {
UDQActive usage ;
UDQParams params ;
UDQConfig conf ( params ) ;
2021-08-19 10:17:12 -05:00
BOOST_CHECK_EQUAL ( usage . iuad ( ) . size ( ) , 0U ) ;
2019-07-26 10:17:06 -05:00
UDAValue uda1 ( " WUX " ) ;
2023-01-31 12:15:55 -06:00
auto segmentMatcherFactory = [ ] ( ) { return std : : make_unique < SegmentMatcher > ( ScheduleState { } ) ; } ;
conf . add_assign ( uda1 . get < std : : string > ( ) , segmentMatcherFactory , std : : vector < std : : string > { } , 100 , 0 ) ;
2019-07-26 10:17:06 -05:00
2021-08-19 10:17:12 -05:00
const auto & iuad = usage . iuad ( ) ;
2019-07-26 10:17:06 -05:00
usage . update ( conf , uda1 , " W1 " , UDAControl : : WCONPROD_ORAT ) ;
2021-08-19 10:17:12 -05:00
BOOST_CHECK_EQUAL ( usage . iuad ( ) . size ( ) , 1U ) ;
2021-08-19 09:52:40 -05:00
BOOST_CHECK_EQUAL ( iuad [ 0 ] . use_count , 1U ) ;
2019-07-26 10:17:06 -05:00
usage . update ( conf , uda1 , " W1 " , UDAControl : : WCONPROD_GRAT ) ;
2021-08-19 10:17:12 -05:00
BOOST_CHECK_EQUAL ( usage . iuad ( ) . size ( ) , 2U ) ;
2021-08-19 09:52:40 -05:00
BOOST_CHECK_EQUAL ( iuad [ 1 ] . use_count , 1U ) ;
2019-07-26 10:17:06 -05:00
2021-08-19 09:52:40 -05:00
const auto & rec = iuad [ 0 ] ;
2019-07-26 10:17:06 -05:00
BOOST_CHECK_EQUAL ( rec . udq , " WUX " ) ;
BOOST_CHECK ( rec . control = = UDAControl : : WCONPROD_ORAT ) ;
2021-08-19 10:17:12 -05:00
for ( std : : size_t index = 0 ; index < usage . iuad ( ) . size ( ) ; index + + ) {
2021-08-19 09:52:40 -05:00
const auto & record = iuad [ index ] ;
2020-09-29 06:54:21 -05:00
BOOST_CHECK_EQUAL ( record . input_index , 0U ) ;
2019-07-26 10:17:06 -05:00
if ( index = = 0 )
BOOST_CHECK ( record . control = = UDAControl : : WCONPROD_ORAT ) ;
else
BOOST_CHECK ( record . control = = UDAControl : : WCONPROD_GRAT ) ;
}
}
2021-05-25 15:23:41 -05:00
BOOST_AUTO_TEST_CASE ( UDQControl_Keyword )
{
BOOST_CHECK_MESSAGE ( UDQ : : keyword ( UDAControl : : WCONPROD_ORAT ) = = UDAKeyword : : WCONPROD , " WCONPROD_ORAT control keyword must be WCONPROD " ) ;
BOOST_CHECK_MESSAGE ( UDQ : : keyword ( UDAControl : : WCONPROD_GRAT ) = = UDAKeyword : : WCONPROD , " WCONPROD_GRAT control keyword must be WCONPROD " ) ;
BOOST_CHECK_MESSAGE ( UDQ : : keyword ( UDAControl : : WCONPROD_WRAT ) = = UDAKeyword : : WCONPROD , " WCONPROD_WRAT control keyword must be WCONPROD " ) ;
BOOST_CHECK_MESSAGE ( UDQ : : keyword ( UDAControl : : WCONPROD_LRAT ) = = UDAKeyword : : WCONPROD , " WCONPROD_LRAT control keyword must be WCONPROD " ) ;
BOOST_CHECK_MESSAGE ( UDQ : : keyword ( UDAControl : : WCONPROD_RESV ) = = UDAKeyword : : WCONPROD , " WCONPROD_RESV control keyword must be WCONPROD " ) ;
BOOST_CHECK_MESSAGE ( UDQ : : keyword ( UDAControl : : WCONPROD_BHP ) = = UDAKeyword : : WCONPROD , " WCONPROD_BHP control keyword must be WCONPROD " ) ;
BOOST_CHECK_MESSAGE ( UDQ : : keyword ( UDAControl : : WCONPROD_THP ) = = UDAKeyword : : WCONPROD , " WCONPROD_THP control keyword must be WCONPROD " ) ;
BOOST_CHECK_MESSAGE ( UDQ : : keyword ( UDAControl : : WCONINJE_RATE ) = = UDAKeyword : : WCONINJE , " WCONINJE_RATE control keyword must be WCONINJE " ) ;
BOOST_CHECK_MESSAGE ( UDQ : : keyword ( UDAControl : : WCONINJE_RESV ) = = UDAKeyword : : WCONINJE , " WCONINJE_RESV control keyword must be WCONINJE " ) ;
BOOST_CHECK_MESSAGE ( UDQ : : keyword ( UDAControl : : WCONINJE_BHP ) = = UDAKeyword : : WCONINJE , " WCONINJE_BHP control keyword must be WCONINJE " ) ;
BOOST_CHECK_MESSAGE ( UDQ : : keyword ( UDAControl : : WCONINJE_THP ) = = UDAKeyword : : WCONINJE , " WCONINJE_THP control keyword must be WCONINJE " ) ;
BOOST_CHECK_MESSAGE ( UDQ : : keyword ( UDAControl : : GCONPROD_OIL_TARGET ) = = UDAKeyword : : GCONPROD , " GCONPROD_OIL_TARGET control keyword must be GCONPROD " ) ;
BOOST_CHECK_MESSAGE ( UDQ : : keyword ( UDAControl : : GCONPROD_WATER_TARGET ) = = UDAKeyword : : GCONPROD , " GCONPROD_WATER_TARGET control keyword must be GCONPROD " ) ;
BOOST_CHECK_MESSAGE ( UDQ : : keyword ( UDAControl : : GCONPROD_GAS_TARGET ) = = UDAKeyword : : GCONPROD , " GCONPROD_GAS_TARGET control keyword must be GCONPROD " ) ;
BOOST_CHECK_MESSAGE ( UDQ : : keyword ( UDAControl : : GCONPROD_LIQUID_TARGET ) = = UDAKeyword : : GCONPROD , " GCONPROD_LIQUID_TARGET control keyword must be GCONPROD " ) ;
BOOST_CHECK_MESSAGE ( UDQ : : keyword ( UDAControl : : GCONINJE_SURFACE_MAX_RATE ) = = UDAKeyword : : GCONINJE , " GCONINJE_SURFACE_MAX_RATE control keyword must be GCONINJE " ) ;
BOOST_CHECK_MESSAGE ( UDQ : : keyword ( UDAControl : : GCONINJE_RESV_MAX_RATE ) = = UDAKeyword : : GCONINJE , " GCONINJE_RESV_MAX_RATE control keyword must be GCONINJE " ) ;
BOOST_CHECK_MESSAGE ( UDQ : : keyword ( UDAControl : : GCONINJE_TARGET_REINJ_FRACTION ) = = UDAKeyword : : GCONINJE , " GCONINJE_TARGET_REINJ_FRACTION control keyword must be GCONINJE " ) ;
BOOST_CHECK_MESSAGE ( UDQ : : keyword ( UDAControl : : GCONINJE_TARGET_VOID_FRACTION ) = = UDAKeyword : : GCONINJE , " GCONINJE_TARGET_VOID_FRACTION control keyword must be GCONINJE " ) ;
2022-04-22 07:46:43 -05:00
BOOST_CHECK_MESSAGE ( UDQ : : keyword ( UDAControl : : WELTARG_ORAT ) = = UDAKeyword : : WELTARG , " WELTARG_ORAT control keyword must be WELTARG " ) ;
BOOST_CHECK_MESSAGE ( UDQ : : keyword ( UDAControl : : WELTARG_WRAT ) = = UDAKeyword : : WELTARG , " WELTARG_WRAT control keyword must be WELTARG " ) ;
BOOST_CHECK_MESSAGE ( UDQ : : keyword ( UDAControl : : WELTARG_GRAT ) = = UDAKeyword : : WELTARG , " WELTARG_GRAT control keyword must be WELTARG " ) ;
BOOST_CHECK_MESSAGE ( UDQ : : keyword ( UDAControl : : WELTARG_LRAT ) = = UDAKeyword : : WELTARG , " WELTARG_LRAT control keyword must be WELTARG " ) ;
BOOST_CHECK_MESSAGE ( UDQ : : keyword ( UDAControl : : WELTARG_RESV ) = = UDAKeyword : : WELTARG , " WELTARG_RESV control keyword must be WELTARG " ) ;
BOOST_CHECK_MESSAGE ( UDQ : : keyword ( UDAControl : : WELTARG_BHP ) = = UDAKeyword : : WELTARG , " WELTARG_BHP control keyword must be WELTARG " ) ;
BOOST_CHECK_MESSAGE ( UDQ : : keyword ( UDAControl : : WELTARG_THP ) = = UDAKeyword : : WELTARG , " WELTARG_THP control keyword must be WELTARG " ) ;
BOOST_CHECK_MESSAGE ( UDQ : : keyword ( UDAControl : : WELTARG_LIFT ) = = UDAKeyword : : WELTARG , " WELTARG_LIFT control keyword must be WELTARG " ) ;
2021-05-25 15:23:41 -05:00
BOOST_CHECK_THROW ( UDQ : : keyword ( static_cast < UDAControl > ( 1729 ) ) ,
std : : logic_error ) ;
}
BOOST_AUTO_TEST_CASE ( UDAControl_IUAD_0 )
{
2022-04-22 04:52:02 -05:00
BOOST_CHECK_EQUAL ( UDQ : : udaCode ( UDAControl : : WCONPROD_ORAT ) , 300'004 ) ;
BOOST_CHECK_EQUAL ( UDQ : : udaCode ( UDAControl : : WCONPROD_GRAT ) , 500'004 ) ;
BOOST_CHECK_EQUAL ( UDQ : : udaCode ( UDAControl : : WCONPROD_WRAT ) , 400'004 ) ;
BOOST_CHECK_EQUAL ( UDQ : : udaCode ( UDAControl : : WCONPROD_LRAT ) , 600'004 ) ;
2022-04-22 05:57:25 -05:00
BOOST_CHECK_EQUAL ( UDQ : : udaCode ( UDAControl : : WCONPROD_RESV ) , 700'004 ) ;
BOOST_CHECK_EQUAL ( UDQ : : udaCode ( UDAControl : : WCONPROD_BHP ) , 800'004 ) ;
BOOST_CHECK_EQUAL ( UDQ : : udaCode ( UDAControl : : WCONPROD_THP ) , 900'004 ) ;
2022-04-22 04:52:02 -05:00
BOOST_CHECK_EQUAL ( UDQ : : udaCode ( UDAControl : : WCONINJE_RATE ) , 400'003 ) ;
BOOST_CHECK_EQUAL ( UDQ : : udaCode ( UDAControl : : WCONINJE_RESV ) , 500'003 ) ;
2022-04-22 05:57:25 -05:00
BOOST_CHECK_EQUAL ( UDQ : : udaCode ( UDAControl : : WCONINJE_BHP ) , 600'003 ) ;
BOOST_CHECK_EQUAL ( UDQ : : udaCode ( UDAControl : : WCONINJE_THP ) , 700'003 ) ;
2022-04-22 04:52:02 -05:00
BOOST_CHECK_EQUAL ( UDQ : : udaCode ( UDAControl : : GCONPROD_OIL_TARGET ) , 200'019 ) ;
BOOST_CHECK_EQUAL ( UDQ : : udaCode ( UDAControl : : GCONPROD_WATER_TARGET ) , 300'019 ) ;
BOOST_CHECK_EQUAL ( UDQ : : udaCode ( UDAControl : : GCONPROD_GAS_TARGET ) , 400'019 ) ;
BOOST_CHECK_EQUAL ( UDQ : : udaCode ( UDAControl : : GCONPROD_LIQUID_TARGET ) , 500'019 ) ;
BOOST_CHECK_EQUAL ( UDQ : : udaCode ( UDAControl : : GCONINJE_SURFACE_MAX_RATE ) , 300'017 ) ;
BOOST_CHECK_EQUAL ( UDQ : : udaCode ( UDAControl : : GCONINJE_RESV_MAX_RATE ) , 400'017 ) ;
BOOST_CHECK_EQUAL ( UDQ : : udaCode ( UDAControl : : GCONINJE_TARGET_REINJ_FRACTION ) , 500'017 ) ;
BOOST_CHECK_EQUAL ( UDQ : : udaCode ( UDAControl : : GCONINJE_TARGET_VOID_FRACTION ) , 600'017 ) ;
2021-08-19 11:21:08 -05:00
2022-04-22 07:46:43 -05:00
BOOST_CHECK_EQUAL ( UDQ : : udaCode ( UDAControl : : WELTARG_ORAT ) , 16 ) ;
BOOST_CHECK_EQUAL ( UDQ : : udaCode ( UDAControl : : WELTARG_WRAT ) , 100'016 ) ;
BOOST_CHECK_EQUAL ( UDQ : : udaCode ( UDAControl : : WELTARG_GRAT ) , 200'016 ) ;
BOOST_CHECK_EQUAL ( UDQ : : udaCode ( UDAControl : : WELTARG_LRAT ) , 300'016 ) ;
BOOST_CHECK_EQUAL ( UDQ : : udaCode ( UDAControl : : WELTARG_RESV ) , 400'016 ) ;
BOOST_CHECK_EQUAL ( UDQ : : udaCode ( UDAControl : : WELTARG_BHP ) , 500'016 ) ;
BOOST_CHECK_EQUAL ( UDQ : : udaCode ( UDAControl : : WELTARG_THP ) , 600'016 ) ;
BOOST_CHECK_EQUAL ( UDQ : : udaCode ( UDAControl : : WELTARG_LIFT ) , 1'000'016 ) ;
2021-08-19 11:21:08 -05:00
BOOST_CHECK_THROW ( UDQ : : udaCode ( static_cast < UDAControl > ( 1729 ) ) ,
2021-05-25 15:23:41 -05:00
std : : logic_error ) ;
}
2019-07-26 10:17:06 -05:00
BOOST_AUTO_TEST_CASE ( IntegrationTest ) {
# include "data/integration_tests/udq.data"
auto schedule = make_schedule ( deck_string ) ;
{
2021-08-19 09:52:40 -05:00
const auto & udq_active = schedule [ 1 ] . udq_active . get ( ) ;
2021-08-19 10:17:12 -05:00
const auto & active = udq_active . iuad ( ) ;
2021-08-19 10:14:06 -05:00
BOOST_CHECK_EQUAL ( active . size ( ) , 6U ) ;
2019-07-26 10:17:06 -05:00
BOOST_CHECK ( active [ 0 ] . control = = UDAControl : : WCONPROD_ORAT ) ;
BOOST_CHECK ( active [ 1 ] . control = = UDAControl : : WCONPROD_LRAT ) ;
BOOST_CHECK ( active [ 2 ] . control = = UDAControl : : WCONPROD_ORAT ) ;
BOOST_CHECK ( active [ 3 ] . control = = UDAControl : : WCONPROD_LRAT ) ;
2020-05-14 10:49:26 -05:00
BOOST_CHECK ( active [ 4 ] . control = = UDAControl : : GCONPROD_LIQUID_TARGET ) ;
BOOST_CHECK ( active [ 5 ] . control = = UDAControl : : GCONPROD_LIQUID_TARGET ) ;
2019-07-26 10:17:06 -05:00
BOOST_CHECK ( active [ 0 ] . udq = = " WUOPRL " ) ;
BOOST_CHECK ( active [ 1 ] . udq = = " WULPRL " ) ;
BOOST_CHECK ( active [ 2 ] . udq = = " WUOPRU " ) ;
BOOST_CHECK ( active [ 3 ] . udq = = " WULPRU " ) ;
2020-05-14 10:49:26 -05:00
BOOST_CHECK ( active [ 4 ] . udq = = " GULPR1 " ) ;
BOOST_CHECK ( active [ 5 ] . udq = = " GUOPR1 " ) ;
2019-07-26 10:17:06 -05:00
BOOST_CHECK ( active [ 0 ] . input_index = = 0 ) ;
BOOST_CHECK ( active [ 1 ] . input_index = = 1 ) ;
BOOST_CHECK ( active [ 2 ] . input_index = = 2 ) ;
BOOST_CHECK ( active [ 3 ] . input_index = = 3 ) ;
2020-05-14 10:49:26 -05:00
BOOST_CHECK ( active [ 4 ] . input_index = = 4 ) ;
BOOST_CHECK ( active [ 5 ] . input_index = = 5 ) ;
2019-07-26 10:17:06 -05:00
BOOST_CHECK ( active [ 0 ] . use_count = = 1 ) ;
BOOST_CHECK ( active [ 1 ] . use_count = = 1 ) ;
BOOST_CHECK ( active [ 2 ] . use_count = = 1 ) ;
BOOST_CHECK ( active [ 3 ] . use_count = = 1 ) ;
2020-05-14 10:49:26 -05:00
BOOST_CHECK ( active [ 4 ] . use_count = = 2 ) ;
BOOST_CHECK ( active [ 5 ] . use_count = = 1 ) ;
2019-07-26 10:17:06 -05:00
}
2019-06-24 09:04:48 -05:00
}
2022-03-11 02:43:35 -06:00
namespace {
2023-01-11 04:23:40 -06:00
Schedule make_udq_schedule ( const std : : string & schedule_string )
{
2019-07-26 10:17:06 -05:00
# include "data/integration_tests/udq2.data"
2022-03-11 02:43:35 -06:00
deck_string + = schedule_string ;
return make_schedule ( deck_string ) ;
}
} // Namespace anonymous
2019-07-26 10:17:06 -05:00
BOOST_AUTO_TEST_CASE ( IntegrationTest2 ) {
const std : : string udq_string = R " (
UDQ
DEFINE WUOPRL ( WOPR PROD1 - 150 ) * 0.90 /
DEFINE WULPRL ( WLPR PROD1 - 200 ) * 0.90 /
DEFINE WUOPRU ( WOPR PROD2 - 250 ) * 0.80 /
DEFINE WULPRU ( WLPR PROD2 - 300 ) * 0.80 /
DEFINE WUOPRL ( WOPR PROD1 - 170 ) * 0.60 /
DEFINE WUXO ( WOPR PROD1 - 170 ) * 0.60 /
DEFINE WUXL ( WOPR PROD1 - 170 ) * 0.60 /
- - units
UNITS WUOPRL SM3 / DAY /
UNITS WULPRL SM3 / DAY /
UNITS WUOPRU SM3 / DAY /
UNITS WULPRU SM3 / DAY /
/
WCONPROD
' PROD1 ' ' OPEN ' ' GRUP ' WUOPRU 1 * 1 * WULPRU 1 * 60.0 / single wells
/
WCONPROD
' PROD2 ' ' OPEN ' ' GRUP ' WUOPRU 1 * 1 * WULPRU 1 * 60.0 / single wells
/
WCONINJE
' WINJ1 ' ' WAT ' ' OPEN ' ' BHP ' 1 * 1200 3500 1 * /
' WINJ2 ' ' WAT ' ' OPEN ' ' BHP ' 1 * 800 3500 1 * /
/
TSTEP
5 /
WCONPROD
' PROD2 ' ' OPEN ' ' GRUP ' WUXO 1 * 1 * WUXL 1 * 60.0 / single wells
/
TSTEP
5 /
WCONPROD
' PROD1 ' ' OPEN ' ' GRUP ' 100 1 * 1 * 100 1 * 60.0 / single wells
/
2019-08-02 07:00:21 -05:00
) " ;
auto schedule = make_udq_schedule ( udq_string ) ;
// First timestep
{
2021-01-27 03:55:35 -06:00
const auto & udq_active = schedule [ 0 ] . udq_active . get ( ) ;
2019-08-02 07:00:21 -05:00
BOOST_CHECK ( udq_active ) ;
2021-08-19 10:17:12 -05:00
const auto & iuad = udq_active . iuad ( ) ;
2021-08-19 10:14:06 -05:00
BOOST_CHECK_EQUAL ( iuad . size ( ) , 2U ) ;
2021-08-19 09:52:40 -05:00
const auto & record0 = iuad [ 0 ] ;
2021-08-19 11:21:08 -05:00
BOOST_CHECK_EQUAL ( record0 . uda_code , 300004 ) ;
2020-09-29 06:54:21 -05:00
BOOST_CHECK_EQUAL ( record0 . input_index , 2U ) ;
BOOST_CHECK_EQUAL ( record0 . use_count , 2U ) ;
BOOST_CHECK_EQUAL ( record0 . use_index , 0U ) ;
2019-08-02 07:00:21 -05:00
2021-08-19 09:52:40 -05:00
const auto & record1 = iuad [ 1 ] ;
2021-08-19 11:21:08 -05:00
BOOST_CHECK_EQUAL ( record1 . uda_code , 600004 ) ;
2020-09-29 06:54:21 -05:00
BOOST_CHECK_EQUAL ( record1 . input_index , 3U ) ;
BOOST_CHECK_EQUAL ( record1 . use_count , 2U ) ;
BOOST_CHECK_EQUAL ( record1 . use_index , 2U ) ;
2019-08-02 07:00:21 -05:00
}
{
// Second timestep
// - The WUOPRU and WULPRU udq are still used in the same manner for the PROD1 well.
// - The new UDQs WUXO and WUXL are now used for the PROD2 well.
2021-01-27 03:55:35 -06:00
const auto & udq_active = schedule [ 1 ] . udq_active . get ( ) ;
2019-08-02 07:00:21 -05:00
BOOST_CHECK ( udq_active ) ;
2021-08-19 10:17:12 -05:00
const auto & iuad = udq_active . iuad ( ) ;
2021-08-19 10:14:06 -05:00
BOOST_CHECK_EQUAL ( iuad . size ( ) , 4U ) ;
2019-08-02 07:00:21 -05:00
2021-08-19 09:52:40 -05:00
const auto & record0 = iuad [ 0 ] ;
2021-08-19 11:21:08 -05:00
BOOST_CHECK_EQUAL ( record0 . uda_code , 300004 ) ;
2020-09-29 06:54:21 -05:00
BOOST_CHECK_EQUAL ( record0 . input_index , 2U ) ;
BOOST_CHECK_EQUAL ( record0 . use_count , 1U ) ;
BOOST_CHECK_EQUAL ( record0 . use_index , 0U ) ;
2019-08-02 07:00:21 -05:00
2021-08-19 09:52:40 -05:00
const auto & record1 = iuad [ 1 ] ;
2021-08-19 11:21:08 -05:00
BOOST_CHECK_EQUAL ( record1 . uda_code , 600004 ) ;
2020-09-29 06:54:21 -05:00
BOOST_CHECK_EQUAL ( record1 . input_index , 3U ) ;
BOOST_CHECK_EQUAL ( record1 . use_count , 1U ) ;
BOOST_CHECK_EQUAL ( record1 . use_index , 1U ) ;
2019-08-02 07:00:21 -05:00
2021-08-19 09:52:40 -05:00
const auto & record2 = iuad [ 2 ] ;
2021-08-19 11:21:08 -05:00
BOOST_CHECK_EQUAL ( record2 . uda_code , 300004 ) ;
2020-09-29 06:54:21 -05:00
BOOST_CHECK_EQUAL ( record2 . input_index , 4U ) ;
BOOST_CHECK_EQUAL ( record2 . use_count , 1U ) ;
BOOST_CHECK_EQUAL ( record2 . use_index , 2U ) ;
2019-08-02 07:00:21 -05:00
2021-08-19 09:52:40 -05:00
const auto & record3 = iuad [ 3 ] ;
2021-08-19 11:21:08 -05:00
BOOST_CHECK_EQUAL ( record3 . uda_code , 600004 ) ;
2020-09-29 06:54:21 -05:00
BOOST_CHECK_EQUAL ( record3 . input_index , 5U ) ;
BOOST_CHECK_EQUAL ( record3 . use_count , 1U ) ;
BOOST_CHECK_EQUAL ( record3 . use_index , 3U ) ;
2019-08-02 07:00:21 -05:00
}
{
// Third timestep
// - The new UDQs WUXO and WUXL are now used for the PROD2 well.
// - The PROD1 well does not use UDQ
2021-01-27 03:55:35 -06:00
const auto & udq_active = schedule [ 2 ] . udq_active . get ( ) ;
2019-08-02 07:00:21 -05:00
BOOST_CHECK ( udq_active ) ;
2021-08-19 10:17:12 -05:00
const auto & iuad = udq_active . iuad ( ) ;
2021-08-19 10:14:06 -05:00
BOOST_CHECK_EQUAL ( iuad . size ( ) , 2U ) ;
2019-08-02 07:00:21 -05:00
2021-08-19 09:52:40 -05:00
const auto & record0 = iuad [ 0 ] ;
2021-08-19 11:21:08 -05:00
BOOST_CHECK_EQUAL ( record0 . uda_code , 300004 ) ;
2020-09-29 06:54:21 -05:00
BOOST_CHECK_EQUAL ( record0 . input_index , 4U ) ;
BOOST_CHECK_EQUAL ( record0 . use_count , 1U ) ;
BOOST_CHECK_EQUAL ( record0 . use_index , 0U ) ;
2019-08-02 07:00:21 -05:00
2021-08-19 09:52:40 -05:00
const auto & record1 = iuad [ 1 ] ;
2021-08-19 11:21:08 -05:00
BOOST_CHECK_EQUAL ( record1 . uda_code , 600004 ) ;
2020-09-29 06:54:21 -05:00
BOOST_CHECK_EQUAL ( record1 . input_index , 5U ) ;
BOOST_CHECK_EQUAL ( record1 . use_count , 1U ) ;
BOOST_CHECK_EQUAL ( record1 . use_index , 1U ) ;
2019-08-02 07:00:21 -05:00
}
2019-10-24 05:50:54 -05:00
{
const auto & udq_config = schedule . getUDQConfig ( 2 ) ;
2019-10-26 18:18:38 -05:00
const auto & def = udq_config . definitions ( ) ;
const auto & def1 = def [ 0 ] ;
2019-10-24 05:50:54 -05:00
const auto & tokens = def1 . func_tokens ( ) ;
2020-09-29 06:54:21 -05:00
BOOST_CHECK_EQUAL ( tokens . count ( UDQTokenType : : number ) , 1U ) ;
BOOST_CHECK_EQUAL ( tokens . count ( UDQTokenType : : ecl_expr ) , 1U ) ;
BOOST_CHECK_EQUAL ( tokens . count ( UDQTokenType : : binary_op_sub ) , 1U ) ;
BOOST_CHECK_EQUAL ( tokens . count ( UDQTokenType : : binary_op_mul ) , 1U ) ;
2021-08-20 05:59:15 -05:00
BOOST_CHECK_THROW ( udq_config [ 1000 ] , std : : exception ) ;
BOOST_CHECK ( udq_config [ 0 ] = = udq_config [ " WUOPRL " ] ) ;
BOOST_CHECK ( udq_config [ 2 ] = = udq_config [ " WUOPRU " ] ) ;
2019-10-24 05:50:54 -05:00
}
2019-08-02 07:00:21 -05:00
}
2019-10-24 05:50:54 -05:00
2020-06-30 04:18:18 -05:00
BOOST_AUTO_TEST_CASE ( UDQ_SCIENTIFIC_LITERAL ) {
std : : string deck_string = R " (
SCHEDULE
UDQ
DEFINE FU 0 - 1.25E-2 * ( 1.0E-1 + 2E-1 ) /
/
2020-06-29 13:48:13 -05:00
2020-06-30 04:18:18 -05:00
) " ;
auto schedule = make_schedule ( deck_string ) ;
const auto & udq = schedule . getUDQConfig ( 0 ) ;
UDQParams udqp ;
auto def0 = udq . definitions ( ) [ 0 ] ;
2021-02-28 10:04:35 -06:00
SummaryState st ( TimeService : : now ( ) ) ;
2020-06-30 04:18:18 -05:00
UDQFunctionTable udqft ( udqp ) ;
2020-08-31 00:38:52 -05:00
UDQState udq_state ( udqp . undefinedValue ( ) ) ;
2023-01-19 06:20:52 -06:00
auto segmentMatcherFactory = [ ] ( ) { return std : : make_unique < SegmentMatcher > ( ScheduleState { } ) ; } ;
2023-10-23 08:07:23 -05:00
UDQContext context ( udqft , { } , { } , segmentMatcherFactory , st , udq_state ) ;
2020-06-30 04:18:18 -05:00
auto res0 = def0 . eval ( context ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_CLOSE ( res0 [ 0 ] . get ( ) , - 0.00125 * 3 , 1e-6 ) ;
2020-06-30 04:18:18 -05:00
}
2020-06-29 13:48:13 -05:00
BOOST_AUTO_TEST_CASE ( UDQ_NEGATIVE_PREFIX_BASIC ) {
std : : string deck_string = R " (
SCHEDULE
UDQ
DEFINE FUMIN0 - 1.5 * FWPR /
DEFINE FUMIN1 - 1.5 * FWPR * ( FGPR + FOPR ) ^ 3 - 2 * FLPR /
2020-08-31 00:38:52 -05:00
DEFINE FU - 2.539E-14 * ( FXP1 + FXP2 ) ^ 3 + 1.4464E-8 * ( FXP1 + FXP2 ) ^ 2 + 0.00028875 * ( FXP1 + FXP2 ) + 2.8541 /
2020-06-29 13:48:13 -05:00
/
) " ;
auto schedule = make_schedule ( deck_string ) ;
const auto & udq = schedule . getUDQConfig ( 0 ) ;
UDQParams udqp ;
auto def0 = udq . definitions ( ) [ 0 ] ;
auto def1 = udq . definitions ( ) [ 1 ] ;
2020-06-29 13:56:16 -05:00
auto def2 = udq . definitions ( ) [ 2 ] ;
2021-02-28 10:04:35 -06:00
SummaryState st ( TimeService : : now ( ) ) ;
2020-06-29 13:48:13 -05:00
UDQFunctionTable udqft ( udqp ) ;
2020-08-31 00:38:52 -05:00
UDQState udq_state ( udqp . undefinedValue ( ) ) ;
2023-01-19 06:20:52 -06:00
auto segmentMatcherFactory = [ ] ( ) { return std : : make_unique < SegmentMatcher > ( ScheduleState { } ) ; } ;
2023-10-23 08:07:23 -05:00
UDQContext context ( udqft , { } , { } , segmentMatcherFactory , st , udq_state ) ;
2020-06-29 13:48:13 -05:00
const double fwpr = 7 ;
const double fopr = 4 ;
const double fgpr = 7 ;
const double flpr = 13 ;
2020-08-31 00:38:52 -05:00
const double fxp1 = 1025 ;
const double fxp2 = 107 ;
2020-06-29 13:48:13 -05:00
st . update ( " FWPR " , fwpr ) ;
st . update ( " FOPR " , fopr ) ;
st . update ( " FGPR " , fgpr ) ;
st . update ( " FLPR " , flpr ) ;
2020-08-31 00:38:52 -05:00
st . update ( " FXP1 " , fxp1 ) ;
st . update ( " FXP2 " , fxp2 ) ;
2020-06-29 13:48:13 -05:00
auto res0 = def0 . eval ( context ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( res0 [ 0 ] . get ( ) , - 1.5 * fwpr ) ;
2020-06-29 13:48:13 -05:00
auto res1 = def1 . eval ( context ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( res1 [ 0 ] . get ( ) , - 1.5 * fwpr * std : : pow ( fgpr + fopr , 3 ) - 2 * flpr ) ;
2020-06-29 13:56:16 -05:00
auto res2 = def2 . eval ( context ) ;
2020-08-31 00:38:52 -05:00
auto right = - 2.5394E-14 * std : : pow ( fxp1 + fxp2 , 3 ) + 1.4464E-8 * std : : pow ( fxp1 + fxp2 , 2 ) + 0.00028875 * ( fxp1 + fxp2 ) + 2.8541 ;
BOOST_CHECK_CLOSE ( res2 [ 0 ] . get ( ) , right , 1e-6 ) ;
2020-08-22 01:45:18 -05:00
}
BOOST_AUTO_TEST_CASE ( UDQ_STARSTAR ) {
std : : string deck_string = R " (
SCHEDULE
UDQ
DEFINE WUOPR2 WOPR ' * ' * WOPR ' * ' /
DEFINE WUGASRA 3 - WGLIR ' * ' /
/
) " ;
auto schedule = make_schedule ( deck_string ) ;
const auto & udq = schedule . getUDQConfig ( 0 ) ;
UDQParams udqp ;
auto def0 = udq . definitions ( ) [ 0 ] ;
auto def1 = udq . definitions ( ) [ 1 ] ;
2021-02-28 10:04:35 -06:00
SummaryState st ( TimeService : : now ( ) ) ;
2020-08-22 01:45:18 -05:00
UDQFunctionTable udqft ( udqp ) ;
2020-08-31 00:38:52 -05:00
UDQState udq_state ( udqp . undefinedValue ( ) ) ;
2023-01-10 03:44:15 -06:00
WellMatcher wm ( NameOrder ( { " W1 " , " W2 " , " W3 " } ) ) ;
2023-01-19 06:20:52 -06:00
auto segmentMatcherFactory = [ ] ( ) { return std : : make_unique < SegmentMatcher > ( ScheduleState { } ) ; } ;
2023-10-23 08:07:23 -05:00
UDQContext context ( udqft , wm , { } , segmentMatcherFactory , st , udq_state ) ;
2020-08-22 01:45:18 -05:00
st . update_well_var ( " W1 " , " WOPR " , 1 ) ;
st . update_well_var ( " W2 " , " WOPR " , 2 ) ;
st . update_well_var ( " W3 " , " WOPR " , 3 ) ;
st . update_well_var ( " W1 " , " WGLIR " , 1 ) ;
st . update_well_var ( " W2 " , " WGLIR " , 2 ) ;
st . update_well_var ( " W3 " , " WGLIR " , 3 ) ;
auto res0 = def0 . eval ( context ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( res0 [ " W1 " ] . get ( ) , 1 ) ;
BOOST_CHECK_EQUAL ( res0 [ " W2 " ] . get ( ) , 4 ) ;
BOOST_CHECK_EQUAL ( res0 [ " W3 " ] . get ( ) , 9 ) ;
2020-08-22 01:45:18 -05:00
auto res1 = def1 . eval ( context ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( res1 [ " W1 " ] . get ( ) , 2 ) ;
BOOST_CHECK_EQUAL ( res1 [ " W2 " ] . get ( ) , 1 ) ;
BOOST_CHECK_EQUAL ( res1 [ " W3 " ] . get ( ) , 0 ) ;
2020-06-29 13:48:13 -05:00
}
2020-06-29 13:56:16 -05:00
2020-08-21 05:22:02 -05:00
BOOST_AUTO_TEST_CASE ( UDQ_UADD_PARSER ) {
std : : string deck_string = R " (
SCHEDULE
UDQ
ASSIGN FU_PAR1 10.0 /
ASSIGN FU_PAR2 2.0 /
ASSIGN FU_PAR3 3.0 /
DEFINE FU_UADD FU_PAR1 UADD FU_PAR2 /
DEFINE FU_UMUL FU_PAR1 UMUL FU_PAR2 + FU_PAR3 /
DEFINE FU_UMIN FU_PAR1 UMIN FU_PAR2 + FU_PAR3 /
/
) " ;
auto schedule = make_schedule ( deck_string ) ;
const auto & udq = schedule . getUDQConfig ( 0 ) ;
2021-02-28 10:04:35 -06:00
SummaryState st ( TimeService : : now ( ) ) ;
2020-08-31 00:38:52 -05:00
auto undefined_value = udq . params ( ) . undefinedValue ( ) ;
UDQState udq_state ( undefined_value ) ;
2023-01-19 06:20:52 -06:00
auto segmentMatcherFactory = [ ] ( ) { return std : : make_unique < SegmentMatcher > ( ScheduleState { } ) ; } ;
udq . eval ( 0 , schedule , { } , segmentMatcherFactory , st , udq_state ) ;
2020-08-21 05:22:02 -05:00
BOOST_CHECK_EQUAL ( st . get ( " FU_UADD " ) , 12 ) ; // 10 + 2
// The Uxxx binary set functions have absolutely lowest priority; i.e. the
// FU_PAR2 + FU_PAR3 expression is evaluated *before* the UMUL and UMIN operations.
BOOST_CHECK_EQUAL ( st . get ( " FU_UMUL " ) , 50 ) ; // 10 * (2 + 3)
BOOST_CHECK_EQUAL ( st . get ( " FU_UMIN " ) , 5 ) ; // min(10, 2+3)
}
2020-08-23 10:19:27 -05:00
BOOST_AUTO_TEST_CASE ( UDQ_DEFINE_ORDER ) {
std : : string deck_string = R " (
SCHEDULE
UDQ
ASSIGN FU_PAR1 1.0 /
DEFINE FU_PAR3 FMWPR /
2020-10-21 06:49:07 -05:00
ASSIGN FU_PAR2 0.0 /
2020-08-23 10:19:27 -05:00
DEFINE FU_PAR2 FU_PAR3 /
/
) " ;
auto schedule = make_schedule ( deck_string ) ;
const auto & udq = schedule . getUDQConfig ( 0 ) ;
2021-02-28 10:04:35 -06:00
SummaryState st ( TimeService : : now ( ) ) ;
2020-08-31 00:38:52 -05:00
auto undefined_value = udq . params ( ) . undefinedValue ( ) ;
UDQState udq_state ( undefined_value ) ;
2020-08-23 10:19:27 -05:00
st . update ( " FMWPR " , 100 ) ;
2023-01-19 06:20:52 -06:00
auto segmentMatcherFactory = [ ] ( ) { return std : : make_unique < SegmentMatcher > ( ScheduleState { } ) ; } ;
udq . eval ( 0 , schedule , { } , segmentMatcherFactory , st , udq_state ) ;
2020-08-23 10:19:27 -05:00
BOOST_CHECK_EQUAL ( st . get ( " FU_PAR2 " ) , 100 ) ;
}
2020-08-31 00:38:52 -05:00
BOOST_AUTO_TEST_CASE ( UDQ_UNDEFINED2 ) {
std : : string deck_string = R " (
SCHEDULE
UDQ
DEFINE FU_PAR2 FU_PAR1 + 1 /
DEFINE FU_PAR3 FU_PAR2 + 1 /
/
) " ;
auto schedule = make_schedule ( deck_string ) ;
const auto & udq = schedule . getUDQConfig ( 0 ) ;
2021-02-28 10:04:35 -06:00
SummaryState st ( TimeService : : now ( ) ) ;
2020-08-31 00:38:52 -05:00
auto undefined_value = udq . params ( ) . undefinedValue ( ) ;
UDQState udq_state ( undefined_value ) ;
2023-01-19 06:20:52 -06:00
auto segmentMatcherFactory = [ ] ( ) { return std : : make_unique < SegmentMatcher > ( ScheduleState { } ) ; } ;
udq . eval ( 0 , schedule , { } , segmentMatcherFactory , st , udq_state ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_EQUAL ( st . get ( " FU_PAR2 " ) , undefined_value ) ;
BOOST_CHECK_EQUAL ( st . get ( " FU_PAR3 " ) , undefined_value ) ;
}
BOOST_AUTO_TEST_CASE ( UDQSTATE ) {
double undefined_value = 1234 ;
UDQState st ( undefined_value ) ;
BOOST_CHECK ( ! st . has ( " FUXX " ) ) ;
BOOST_CHECK ( ! st . has_well_var ( " OP1 " , " WUXX " ) ) ;
BOOST_CHECK ( ! st . has_group_var ( " G1 " , " GUXX " ) ) ;
// Try to get from symbol which is not UDQ -> logic_error
BOOST_CHECK_THROW ( st . get ( " FOPR " ) , std : : logic_error ) ;
// Try to get from a UDQ which has not registered -> out_of_range
BOOST_CHECK_THROW ( st . get ( " FUPR " ) , std : : out_of_range ) ;
auto fxpr = UDQSet : : scalar ( " FXPR " , 100 ) ;
2020-11-15 03:03:34 -06:00
BOOST_CHECK_THROW ( st . add_define ( 0 , " FXPR " , fxpr ) , std : : logic_error ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK_THROW ( st . get_well_var ( " OP1 " , " WUPR " ) , std : : out_of_range ) ;
auto fupr = UDQSet : : scalar ( " FUPR " , 100 ) ;
2020-11-15 03:03:34 -06:00
st . add_define ( 0 , " FUPR " , fupr ) ;
2020-08-31 00:38:52 -05:00
// This is not a well quantity
BOOST_CHECK_THROW ( st . get_well_var ( " OP1 " , " FUPR " ) , std : : logic_error ) ;
BOOST_CHECK_EQUAL ( 100 , st . get ( " FUPR " ) ) ;
auto wupr = UDQSet : : wells ( " WUPR " , { " P1 " , " P2 " } ) ;
wupr . assign ( " P1 " , 75 ) ;
2020-11-15 03:03:34 -06:00
st . add_define ( 0 , " WUPR " , wupr ) ;
2020-08-31 00:38:52 -05:00
BOOST_CHECK ( st . has_well_var ( " P1 " , " WUPR " ) ) ;
// We have a well P2 - but we have not assigned a value to it!
BOOST_CHECK ( ! st . has_well_var ( " P2 " , " WUPR " ) ) ;
BOOST_CHECK_EQUAL ( st . get_well_var ( " P1 " , " WUPR " ) , 75 ) ;
BOOST_CHECK_EQUAL ( st . get_well_var ( " P2 " , " WUPR " ) , undefined_value ) ;
}
2020-08-21 05:22:02 -05:00
BOOST_AUTO_TEST_CASE ( UDQ_UADD_PARSER2 ) {
std : : string deck_string = R " (
SCHEDULE
UDQ
ASSIGN FU_PAR1 1.0 / - - xxxxxxxxxxxxxxxxxxxxxx
ASSIGN FU_PAR2 0.0 /
ASSIGN FU_PAR3 0.0 /
ASSIGN FU_PAR4 0.0 /
ASSIGN FU_PAR5 0.0 /
- - xxxxx xxxx
DEFINE FU_PAR6 FMWPR /
- - xxxxxxxxxxxxxxxxxxxx
DEFINE FU_PAR7 FMWIN /
DEFINE FU_PAR8 FMWPA /
DEFINE FU_PAR9 FMWIA /
- - xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
DEFINE FU_PAR10 ( FU_PAR6 - FU_PAR2 ) + ( FU_PAR8 - FU_PAR4 ) /
DEFINE FU_PAR11 ( FU_PAR7 - FU_PAR3 ) + ( FU_PAR9 - FU_PAR5 ) /
DEFINE FU_PAR12 FU_PAR10 > 0 /
DEFINE FU_PAR13 FU_PAR11 > 0 /
DEFINE FU_PAR14 FU_PAR12 * FU_PAR10 /
DEFINE FU_PAR15 FU_PAR13 * FU_PAR11 /
DEFINE FU_PAR2 FU_PAR6 /
DEFINE FU_PAR3 FU_PAR7 /
DEFINE FU_PAR4 FU_PAR8 /
DEFINE FU_PAR5 FU_PAR9 /
- - xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
ASSIGN FU_PAR16 0.08 /
ASSIGN FU_PAR17 100.0 /
ASSIGN FU_PAR18 6.0 /
ASSIGN FU_PAR19 0.0 /
- - xxxxxxxxxxxxx
DEFINE FU_PAR19 FU_PAR19 + TIMESTEP /
ASSIGN FU_PAR20 800.0 /
ASSIGN FU_PAR21 0.0 /
- - xxxxxxxxxxxxxxxxx
DEFINE FU_PAR21 FU_PAR21 UADD FU_PAR20 * ( FU_PAR14 + FU_PAR15 ) / ( ( 1.0 + 0.08 ) ^ ( FU_PAR19 / 365 ) ) /
- - xxxxxxxxxxxxxxxxxxxx
ASSIGN FU_PAR22 0.0 /
DEFINE FU_PAR22 FU_PAR22 + FOPR * TIMESTEP * 1E-06 * 6.29 * FU_PAR17 * FU_PAR18 / ( ( 1.0 + 0.08 ) ^ ( FU_PAR19 / 365 ) ) /
DEFINE FU_PAR23 FU_PAR22 - FU_PAR21 /
- - xxxxxxxxxxxxxxxxxxxxxxxx
ASSIGN FU_PAR24 0.9 /
DEFINE FU_PAR24 FU_PAR24 UADD ( FU_PAR14 + FU_PAR15 ) /
- - xxxxxxxxxxxxxxxxxxxxxxxxxxxx
DEFINE WUGASRA 750000 - WGLIR ' * ' /
/
) " ;
2020-08-23 10:19:27 -05:00
auto schedule = make_schedule ( deck_string ) ;
2020-08-31 00:38:52 -05:00
const auto & udq = schedule . getUDQConfig ( 0 ) ;
auto undefined_value = udq . params ( ) . undefinedValue ( ) ;
UDQState udq_state ( undefined_value ) ;
2021-02-28 10:04:35 -06:00
SummaryState st ( TimeService : : now ( ) ) ;
2020-08-31 00:38:52 -05:00
2020-09-08 05:05:52 -05:00
st . update ( " TIMESTEP " , 100 ) ;
2020-08-23 10:19:27 -05:00
st . update ( " FMWPR " , 100 ) ;
st . update ( " FMWIN " , 100 ) ;
st . update ( " FMWPA " , 100 ) ;
st . update ( " FMWIA " , 100 ) ;
st . update ( " FOPR " , 100 ) ;
st . update_well_var ( " W1 " , " WGLIR " , 1 ) ;
st . update_well_var ( " W2 " , " WGLIR " , 2 ) ;
st . update_well_var ( " W3 " , " WGLIR " , 3 ) ;
2021-01-28 10:47:51 -06:00
NameOrder wo ( { " W1 " , " W2 " , " W3 " } ) ;
2023-01-10 03:44:15 -06:00
WellMatcher wm ( wo ) ;
2023-01-19 06:20:52 -06:00
auto segmentMatcherFactory = [ ] ( ) { return std : : make_unique < SegmentMatcher > ( ScheduleState { } ) ; } ;
udq . eval ( 0 , schedule , wm , segmentMatcherFactory , st , udq_state ) ;
const auto required_keys = [ & udq ] ( )
2020-10-23 08:14:59 -05:00
{
2023-01-19 06:20:52 -06:00
auto keys = std : : unordered_set < std : : string > { } ;
udq . required_summary ( keys ) ;
auto required = std : : vector < std : : string > { keys . begin ( ) , keys . end ( ) } ;
std : : sort ( required . begin ( ) , required . end ( ) ) ;
return required ;
} ( ) ;
const auto expected_keys = std : : vector < std : : string > {
" FMWIA " ,
" FMWIN " ,
" FMWPA " ,
" FMWPR " ,
" FOPR " ,
" TIMESTEP " ,
" WGLIR " ,
} ;
BOOST_CHECK_EQUAL_COLLECTIONS ( required_keys . begin ( ) , required_keys . end ( ) ,
expected_keys . begin ( ) , expected_keys . end ( ) ) ;
2020-08-21 05:22:02 -05:00
}
2020-08-31 00:38:52 -05:00
BOOST_AUTO_TEST_CASE ( UDQ_UNDEFINED ) {
std : : string deck_string = R " (
2020-09-08 05:08:16 -05:00
SCHEDULE
2020-08-31 00:38:52 -05:00
- - udq # 2
UDQ
- - - - XX xxxx xxx
- - xxxx xxxx xxxx xxxx
ASSIGN FU_VAR1 0 /
DEFINE FU_VAR1 - 2.539E-14 * ( FU_VAR91 + FU_VAR90 ) ^ 3 + 1.4464E-8 * ( FU_VAR91 + FU_VAR90 ) ^ 2 + 0.00028875 * ( FU_VAR91 + FU_VAR90 ) + 2.8541 /
- - xxxx xx xxxx xxx xxxx xxxx
ASSIGN FU_VAR2 0 /
DEFINE FU_VAR3 FU_VAR1 > 10 /
DEFINE FU_VAR2 NINT ( FU_VAR91 / 35000 + 0.499 ) * FU_VAR3 /
- - xxxx xxx XX xxx xxxx xxxx
ASSIGN FU_VAR4 0 /
- - Xxxx xxx XX xxx xxxx , xxxx
ASSIGN FU_VAR5 0 /
DEFINE FU_VAR6 FU_VAR2 ! = 0 /
DEFINE FU_VAR7 FU_VAR6 * FU_VAR2 - 999 * ( 1 - FU_VAR6 ) / - - Avoiding div by 0
DEFINE FU_VAR5 FU_VAR6 * FU_VAR91 / FU_VAR7 / 24 / 0.95 /
- - Xxx xxx XX xxx xxx , xxxxx
DEFINE FU_VAR8 FU_VAR4 ! = 0 /
ASSIGN FU_VAR9 0 /
- - XX Xxx xxxxx xxxxx xxxxx
ASSIGN FU_VAR10 0 /
DEFINE FU_VAR10 - 0.00000041232 * FU_VAR5 ^ 2 + 0.0010395 * FU_VAR5 + 0.16504 /
- - XX xxx xxxxx xxxxx xxxxx
ASSIGN FU_VAR11 0 /
- - xxxxx xxxxx xxxxx xxxxx , xX
ASSIGN FU_VAR12 0 /
ASSIGN FU_VAR13 0 /
ASSIGN FU_VAR14 0 /
DEFINE FU_VAR12 FU_VAR2 * FU_VAR5 * 1E5 * ( ( FU_VAR1 - 10 ) / 3600 ) / 1000 / FU_VAR10 / 0.8938 /
DEFINE FU_VAR14 FU_VAR12 + FU_VAR13 /
- - - - - Xxxxx xxxxx xxxxx
- - xxxxx xx XX xxxxx xxxxx xxxxx
ASSIGN FU_VAR15 0 /
DEFINE FU_VAR15 NINT ( ( FU_P1SWI + FU_P1WPR ) / 30000 + 0.499 ) /
- - xxxxx xx XX xxxxx xxxxx xxxxx
ASSIGN FU_VAR16 0 /
- - xxxx xx XX XZ , xx / x
ASSIGN FU_VAR17 0 /
DEFINE FU_VAR18 FU_VAR15 ! = 0 /
DEFINE FU_VAR17 FU_P1WPB * ( FU_P1WPR + FU_P1SWI ) / ( FU_VAR15 + 0.0001 ) / 24 / 0.95 /
- - xxxx xxx xxxx xxxx xxxx , xxxx
DEFINE FU_VAR19 FU_VAR16 ! = 0 /
ASSIGN FU_VAR20 0 /
- - xxxx xxxx xxxx xxxx
ASSIGN FU_VAR21 0 /
DEFINE FU_VAR21 - 0.00000035417 * FU_VAR17 ^ 2 + 0.0010673 * FU_VAR17 + 0.029286 /
- - XX xxxx xxxx xxxx
ASSIGN FU_VAR22 0 /
- - XX XX xxxx xxxx , xX
ASSIGN FU_VAR23 0 /
DEFINE FU_VAR23 FU_VAR15 * FU_VAR17 * 1E5 * ( ( 150 - 10 ) / 3600 ) / 1000 / FU_VAR21 / 0.8938 /
- - xx XX xx xx , xX
ASSIGN FU_VAR24 0 /
- - xxxx xxxx xxxx xxxx , xxxx
DEFINE FU_VAR25 FU_VAR23 + FU_VAR24 /
- - - - - xxxx xxxx
- - xxxx xxxx xxxx , X xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
ASSIGN FU_VAR26 0 /
- - xxxx xxxx xxxx xxxx
ASSIGN FU_VAR27 0 /
DEFINE FU_VAR27 ( ( FU_P1TGP / 1E6 * 4546.667 ) / 0.9215 + 1474 ) * ( 1 - FU_VAR26 ) + ( ( FU_P1TGP / 1E6 * 4911 ) / 0.9215 + 1474 ) * FU_VAR26 /
- - xxxx xxxx xxxx xxxx
ASSIGN FU_VAR28 0 /
- - xxxx xxxx xxxx
ASSIGN FU_VAR29 0 /
DEFINE FU_VAR29 FU_VAR27 + FU_VAR28 /
- - - - - xxxx xxxx
ASSIGN FU_VAR30 6682 /
ASSIGN FU_VAR31 0 /
ASSIGN FU_VAR32 4155 / - - xxxx xx xxxx xxxx XX xxxx
ASSIGN FU_VAR33 9685 /
ASSIGN FU_VAR34 4000 /
ASSIGN FU_VAR35 1230 / - - xxxx xx xxxx xxxx XX xxxx
- - Total base load
ASSIGN FU_VAR36 0 /
DEFINE FU_VAR36 FU_P1BL + FU_P2BL + FU_VAR32 + FU_VAR33 + FU_VAR34 + FU_VAR35 /
- - - - - XX xxxx xxxx
ASSIGN FU_VAR37 2300 /
ASSIGN FU_VAR38 0 / - - xxxxxx xx xxxx xxxx XX xxxx
ASSIGN FU_VAR39 2300 / - - xxxx * Y xxxx xx Z xxxx XX xxxx
- - xxxx xxxx xxxx xxxx
ASSIGN FU_VAR40 0 /
DEFINE FU_VAR40 FU_VAR37 + FU_VAR38 + FU_VAR39 /
- - - - - xxxx xxxx xxxx xxxx
- - xxxx xxxx
ASSIGN FU_VAR41 0 /
DEFINE FU_VAR41 0.005 * FU_VAR90 /
DEFINE FU_VAR42 FU_P2WPR < FU_VAR41 /
ASSIGN FU_VAR43 0 /
- - xxxx xxxx
ASSIGN FU_VAR44 0 /
- - xxxx xxxx xxxx
ASSIGN FU_VAR45 0 /
DEFINE FU_VAR45 FU_VAR43 + FU_VAR44 /
- - - - - xxxx xxxx xxxx
ASSIGN FU_VAR46 0 /
DEFINE FU_VAR47 FU_P1SWI > 10 /
DEFINE FU_VAR46 NINT ( FU_P1SWI / 36000 + 0.499 ) * 761 / 0.9025 * FU_VAR47 /
ASSIGN FU_VAR48 0 /
DEFINE FU_VAR49 FU_P1WPR > 10 /
DEFINE FU_VAR48 NINT ( FU_P1WPR / 30576 + 0.499 ) * 864 / 0.9025 * FU_VAR49 /
DEFINE FU_VAR50 FU_P2SWI > 10 /
ASSIGN FU_VAR51 0 /
DEFINE FU_VAR52 FU_P2WPR > 10 /
ASSIGN FU_VAR53 0 /
- - xxxx xxxx xxxx
ASSIGN FU_VAR54 0 /
DEFINE FU_VAR54 FU_VAR46 + FU_VAR48 + FU_VAR51 + FU_VAR53 /
- - - - - xxxx xxxx loadxxxxs
- - xxxx xxxx xxxx xxxx xxxx , xxxxxxxx
ASSIGN FU_VAR55 0 /
DEFINE FU_VAR55 FU_VAR91 * 30.6571 / 1000 / 0.8754 /
- - xxxx xxxx xxxx xxxx xxxx , xxxx
ASSIGN FU_VAR56 0 /
- - xxxx
ASSIGN FU_VAR57 0 /
DEFINE FU_VAR57 FU_VAR91 * 61.4286 / 1000 / 0.9215 + 280 /
- - xxxx
ASSIGN FU_VAR58 0 /
- - xxxx
ASSIGN FU_VAR59 0 /
DEFINE FU_VAR59 FU_P1TGP * 120 / 1E6 /
- - xxxx xxxx xxxx xxxx , xxxx
ASSIGN FU_VAR60 0 /
DEFINE FU_VAR60 ( FU_VAR91 + FU_VAR90 ) * 5.52 / 1000 /
- - xxxx xxxx xxxx xxxx , xxxx
ASSIGN FU_VAR61 0 /
DEFINE FU_VAR61 FU_VAR60 + FU_VAR59 + FU_VAR58 + FU_VAR57 + FU_VAR56 + FU_VAR55 /
- - - - - xxxx - xxxx , xxxx
ASSIGN FU_VAR62 0 /
DEFINE FU_VAR62 ( FU_VAR61 + FU_VAR54 + FU_VAR45 + FU_VAR40 + FU_VAR36 + FU_VAR29 + FU_VAR25 + FU_VAR14 ) / 1000 /
- - xxxx xxxx , xxxx
ASSIGN FU_VAR63 0 / - - xxxx xxxx xxxx xxxx xxxx xxxx xxxx
- - Allowance , MW
ASSIGN FU_VAR64 5 / - - xxxx xxxx xxxx MxxxxW xxxx xxxx XX xxxx
- - xxxx
ASSIGN FU_VAR65 0 /
DEFINE FU_VAR65 0.02 * FU_VAR62 /
- - - - - xxxx xxxx xxxx xxxx , xxxx
ASSIGN FU_VAR66 0 /
DEFINE FU_VAR66 FU_VAR65 + FU_VAR64 + FU_VAR63 + FU_VAR62 /
- - - - xxxx xxxx xxxx
DEFINE FU_VAR67 0 /
DEFINE FU_VAR67 FU_VAR66 * 0.79 /
- - - - xxxx xxxx xxxx xxxx
DEFINE FU_VAR68 0 /
DEFINE FU_VAR68 FU_VAR67 * 1.08 /
/
- - udq # 6
UDQ
ASSIGN FU_VAR90 0.0 /
DEFINE FU_VAR91 GOPR TEST /
/
) " ;
auto schedule = make_schedule ( deck_string ) ;
const auto & udq = schedule . getUDQConfig ( 0 ) ;
auto undefined_value = udq . params ( ) . undefinedValue ( ) ;
UDQState udq_state ( undefined_value ) ;
2021-02-28 10:04:35 -06:00
SummaryState st ( TimeService : : now ( ) ) ;
2020-08-31 00:38:52 -05:00
st . update ( " FMWPR " , 100 ) ;
st . update ( " FMWIN " , 100 ) ;
st . update ( " FMWPA " , 100 ) ;
st . update ( " FMWIA " , 100 ) ;
st . update ( " FOPR " , 100 ) ;
2020-09-08 05:05:52 -05:00
st . update ( " TIMESTEP " , 100 ) ;
2020-08-31 00:38:52 -05:00
st . update_well_var ( " W1 " , " WGLIR " , 1 ) ;
st . update_well_var ( " W2 " , " WGLIR " , 2 ) ;
st . update_well_var ( " W3 " , " WGLIR " , 3 ) ;
2020-09-08 05:08:16 -05:00
st . update_group_var ( " TEST " , " GOPR " , 1 ) ;
2020-08-31 00:38:52 -05:00
2023-01-19 06:20:52 -06:00
auto segmentMatcherFactory = [ ] ( ) { return std : : make_unique < SegmentMatcher > ( ScheduleState { } ) ; } ;
udq . eval ( 0 , schedule , { } , segmentMatcherFactory , st , udq_state ) ;
2020-08-31 00:38:52 -05:00
}
2020-09-07 11:05:56 -05:00
2020-09-08 01:19:17 -05:00
BOOST_AUTO_TEST_CASE ( UDQ_KEY_ERROR ) {
2020-09-07 11:05:56 -05:00
std : : string deck_string = R " (
- - udq # 2
SCHEDULE
UDQ
2020-09-08 01:19:17 -05:00
DEFINE FU_VAR1 FOPR * 5 /
2020-09-07 11:05:56 -05:00
/
) " ;
auto schedule = make_schedule ( deck_string ) ;
const auto & udq = schedule . getUDQConfig ( 0 ) ;
auto undefined_value = udq . params ( ) . undefinedValue ( ) ;
UDQState udq_state ( undefined_value ) ;
2021-02-28 10:04:35 -06:00
SummaryState st ( TimeService : : now ( ) ) ;
2020-09-07 11:05:56 -05:00
2023-01-19 06:20:52 -06:00
auto segmentMatcherFactory = [ ] ( ) { return std : : make_unique < SegmentMatcher > ( ScheduleState { } ) ; } ;
BOOST_CHECK_THROW ( udq . eval ( 0 , schedule , { } , segmentMatcherFactory , st , udq_state ) , std : : exception ) ;
2020-09-07 11:05:56 -05:00
}
2020-09-08 05:08:16 -05:00
BOOST_AUTO_TEST_CASE ( UDQ_ASSIGN ) {
std : : string deck_string = R " (
- - udq # 2
SCHEDULE
UDQ
ASSIGN FU_VAR1 5 /
DEFINE FU_VAR1 FU_VAR1 + 5 /
/
) " ;
auto schedule = make_schedule ( deck_string ) ;
const auto & udq = schedule . getUDQConfig ( 0 ) ;
auto undefined_value = udq . params ( ) . undefinedValue ( ) ;
UDQState udq_state ( undefined_value ) ;
2021-02-28 10:04:35 -06:00
SummaryState st ( TimeService : : now ( ) ) ;
2023-01-19 06:20:52 -06:00
const auto required_keys = [ & udq ] ( )
2020-10-23 08:14:59 -05:00
{
2023-01-19 06:20:52 -06:00
auto keys = std : : unordered_set < std : : string > { } ;
udq . required_summary ( keys ) ;
auto required = std : : vector < std : : string > { keys . begin ( ) , keys . end ( ) } ;
std : : sort ( required . begin ( ) , required . end ( ) ) ;
return required ;
} ( ) ;
const auto expected_keys = std : : vector < std : : string > { } ;
BOOST_CHECK_EQUAL_COLLECTIONS ( required_keys . begin ( ) , required_keys . end ( ) ,
expected_keys . begin ( ) , expected_keys . end ( ) ) ;
2020-09-08 05:08:16 -05:00
2023-01-19 06:20:52 -06:00
auto segmentMatcherFactory = [ ] ( ) { return std : : make_unique < SegmentMatcher > ( ScheduleState { } ) ; } ;
udq . eval ( 0 , schedule , { } , segmentMatcherFactory , st , udq_state ) ;
2020-09-08 05:08:16 -05:00
BOOST_CHECK_EQUAL ( st . get ( " FU_VAR1 " ) , 10 ) ;
}
BOOST_AUTO_TEST_CASE ( UDQ_ASSIGN_REASSIGN ) {
std : : string deck_string = R " (
- - udq # 2
SCHEDULE
UDQ
ASSIGN FU_VAR1 0 /
DEFINE FU_VAR1 FU_VAR1 + 1 /
/
TSTEP
1 1 1 1 1 /
UDQ
ASSIGN FU_VAR1 0 /
DEFINE FU_VAR1 FU_VAR1 + 1 /
/
TSTEP
1 1 1 1 1 /
UDQ
ASSIGN FU_VAR1 0 /
/
TSTEP
1 1 1 1 1 /
) " ;
auto schedule = make_schedule ( deck_string ) ;
UDQState udq_state ( 0 ) ;
2021-02-28 10:04:35 -06:00
SummaryState st ( TimeService : : now ( ) ) ;
2020-09-08 05:08:16 -05:00
// Counting: 1,2,3,4,5
for ( std : : size_t report_step = 0 ; report_step < 5 ; report_step + + ) {
const auto & udq = schedule . getUDQConfig ( report_step ) ;
2023-01-19 06:20:52 -06:00
auto segmentMatcherFactory = [ ] ( ) { return std : : make_unique < SegmentMatcher > ( ScheduleState { } ) ; } ;
udq . eval ( report_step , schedule , schedule . wellMatcher ( report_step ) , segmentMatcherFactory , st , udq_state ) ;
2020-09-08 05:08:16 -05:00
auto fu_var1 = st . get ( " FU_VAR1 " ) ;
BOOST_CHECK_EQUAL ( fu_var1 , report_step + 1 ) ;
}
// Reset to zero and count: 1,2,3,4,5
for ( std : : size_t report_step = 5 ; report_step < 10 ; report_step + + ) {
const auto & udq = schedule . getUDQConfig ( report_step ) ;
2023-01-19 06:20:52 -06:00
auto segmentMatcherFactory = [ ] ( ) { return std : : make_unique < SegmentMatcher > ( ScheduleState { } ) ; } ;
udq . eval ( report_step , schedule , schedule . wellMatcher ( report_step ) , segmentMatcherFactory , st , udq_state ) ;
2020-09-08 05:08:16 -05:00
auto fu_var1 = st . get ( " FU_VAR1 " ) ;
BOOST_CHECK_EQUAL ( fu_var1 , report_step - 4 ) ;
}
// Reset to zero and stay there.
for ( std : : size_t report_step = 10 ; report_step < 15 ; report_step + + ) {
const auto & udq = schedule . getUDQConfig ( report_step ) ;
2023-01-19 06:20:52 -06:00
auto segmentMatcherFactory = [ ] ( ) { return std : : make_unique < SegmentMatcher > ( ScheduleState { } ) ; } ;
udq . eval ( report_step , schedule , schedule . wellMatcher ( report_step ) , segmentMatcherFactory , st , udq_state ) ;
2020-09-08 05:08:16 -05:00
auto fu_var1 = st . get ( " FU_VAR1 " ) ;
BOOST_CHECK_EQUAL ( fu_var1 , 0 ) ;
}
2021-02-04 04:09:32 -06:00
2021-02-03 01:31:59 -06:00
const auto & unique = schedule . unique < UDQConfig > ( ) ;
BOOST_CHECK_EQUAL ( unique . size ( ) , 3 ) ;
BOOST_CHECK_EQUAL ( unique [ 0 ] . first , 0 ) ;
BOOST_CHECK_EQUAL ( unique [ 1 ] . first , 5 ) ;
BOOST_CHECK_EQUAL ( unique [ 2 ] . first , 10 ) ;
BOOST_CHECK ( unique [ 0 ] . second = = schedule . getUDQConfig ( 0 ) ) ;
BOOST_CHECK ( unique [ 1 ] . second = = schedule . getUDQConfig ( 5 ) ) ;
BOOST_CHECK ( unique [ 2 ] . second = = schedule . getUDQConfig ( 10 ) ) ;
2020-09-08 05:08:16 -05:00
}
2020-10-22 07:40:32 -05:00
BOOST_AUTO_TEST_CASE ( UDQ_DIV_TEST ) {
KeywordLocation location ;
UDQFunctionTable udqft ;
UDQParams udqp ;
2020-11-15 03:03:34 -06:00
UDQDefine def_div ( udqp , " FU " , 0 , location , { " 128 " , " / " , " 2 " , " / " , " 4 " , " / " , " 8 " } ) ;
2021-02-28 10:04:35 -06:00
SummaryState st ( TimeService : : now ( ) ) ;
2020-10-22 07:40:32 -05:00
UDQState udq_state ( udqp . undefinedValue ( ) ) ;
2023-01-19 06:20:52 -06:00
auto segmentMatcherFactory = [ ] ( ) { return std : : make_unique < SegmentMatcher > ( ScheduleState { } ) ; } ;
2023-10-23 08:07:23 -05:00
UDQContext context ( udqft , { } , { } , segmentMatcherFactory , st , udq_state ) ;
2020-10-22 07:40:32 -05:00
auto res_div = def_div . eval ( context ) ;
BOOST_CHECK_EQUAL ( res_div [ 0 ] . get ( ) , 2.0 ) ;
}
2020-10-25 14:46:23 -05:00
BOOST_AUTO_TEST_CASE ( UDQ_LEADING_SIGN ) {
std : : string deck_string = R " (
SCHEDULE
UDQ
DEFINE FU_VAR1 - 100 + 215 /
DEFINE FU_VAR2 ( - 100 + 200 ) / 10 /
DEFINE FU_VAR3 - ( 100 + 200 ) * - 10 /
DEFINE FU_VAR4 2 ^ - 1 /
ASSIGN FU_VAR6 2 /
ASSIGN FU_VAR7 3 /
DEFINE FU_VAR5 ( - 0.00000041232 * ( FU_VAR6 ^ 2 ) ) + ( 0.0010395 * FU_VAR7 ) + 0.16504 /
/
) " ;
auto schedule = make_schedule ( deck_string ) ;
UDQState udq_state ( 0 ) ;
2021-02-28 10:04:35 -06:00
SummaryState st ( TimeService : : now ( ) ) ;
2020-10-25 14:46:23 -05:00
const auto & udq = schedule . getUDQConfig ( 0 ) ;
2023-01-19 06:20:52 -06:00
auto segmentMatcherFactory = [ ] ( ) { return std : : make_unique < SegmentMatcher > ( ScheduleState { } ) ; } ;
udq . eval ( 0 , schedule , { } , segmentMatcherFactory , st , udq_state ) ;
2020-10-25 14:46:23 -05:00
auto fu_var1 = st . get ( " FU_VAR1 " ) ;
auto fu_var2 = st . get ( " FU_VAR2 " ) ;
auto fu_var3 = st . get ( " FU_VAR3 " ) ;
auto fu_var4 = st . get ( " FU_VAR4 " ) ;
auto fu_var5 = st . get ( " FU_VAR5 " ) ;
BOOST_CHECK_EQUAL ( fu_var1 , 115 ) ;
BOOST_CHECK_EQUAL ( fu_var2 , 10 ) ;
BOOST_CHECK_EQUAL ( fu_var3 , 3000 ) ;
BOOST_CHECK_EQUAL ( fu_var4 , 0.5 ) ;
BOOST_CHECK_CLOSE ( fu_var5 , - 0.00000041232 * 4 + 0.0010395 * 3 + 0.16504 , 1e-5 ) ;
}
2020-10-30 07:36:41 -05:00
BOOST_AUTO_TEST_CASE ( UDQ_WLIST ) {
std : : string deck_string = R " (
SCHEDULE
WELSPECS
' P1 ' ' OP ' 20 51 3.92 ' OIL ' 3 * NO /
' P2 ' ' OP ' 20 51 3.92 ' OIL ' 3 * NO /
' P3 ' ' OP ' 20 51 3.92 ' OIL ' 3 * NO /
' P4 ' ' OP ' 20 51 3.92 ' OIL ' 3 * NO /
/
WLIST
' * ILIST ' ' NEW ' P1 P2 P3 /
/
UDQ
DEFINE FU_VAR1 SUM ( WOPR ' * ILIST ' ) /
DEFINE FU_VAR2 SUM ( WOPR ' * ' ) /
2020-10-30 16:17:28 -05:00
DEFINE FU_VAR3 WOPR ' P4 ' /
2020-10-30 07:36:41 -05:00
/
) " ;
auto schedule = make_schedule ( deck_string ) ;
UDQState udq_state ( 0 ) ;
2021-02-28 10:04:35 -06:00
SummaryState st ( TimeService : : now ( ) ) ;
2020-10-30 07:36:41 -05:00
const auto & udq = schedule . getUDQConfig ( 0 ) ;
st . update_well_var ( " P1 " , " WOPR " , 1 ) ;
st . update_well_var ( " P2 " , " WOPR " , 2 ) ;
st . update_well_var ( " P3 " , " WOPR " , 3 ) ;
st . update_well_var ( " P4 " , " WOPR " , 4 ) ;
2023-01-19 06:20:52 -06:00
auto segmentMatcherFactory = [ ] ( ) { return std : : make_unique < SegmentMatcher > ( ScheduleState { } ) ; } ;
udq . eval ( 0 , schedule , schedule . wellMatcher ( 0 ) , segmentMatcherFactory , st , udq_state ) ;
2020-10-30 07:36:41 -05:00
auto fu_var1 = st . get ( " FU_VAR1 " ) ;
auto fu_var2 = st . get ( " FU_VAR2 " ) ;
2020-10-30 16:17:28 -05:00
auto fu_var3 = st . get ( " FU_VAR3 " ) ;
2020-10-30 07:36:41 -05:00
BOOST_CHECK_EQUAL ( fu_var1 , 6 ) ;
BOOST_CHECK_EQUAL ( fu_var2 , 10 ) ;
2020-10-30 16:17:28 -05:00
BOOST_CHECK_EQUAL ( fu_var3 , 4 ) ;
2020-10-30 07:36:41 -05:00
}
2020-11-05 08:35:55 -06:00
BOOST_AUTO_TEST_CASE ( UDQ_MINUS_PAREN ) {
std : : string deck_string = R " (
SCHEDULE
UDQ
DEFINE FU_VAR1 - ( - 10 + 15 ) * 10 /
DEFINE FU_VAR2 - ( - ( 10 ) + 15 ) * 10 /
DEFINE FU_VAR3 - ( - 10 + 15 ) * - 10 /
DEFINE FU_VAR4 - ( - ( 10 ) + 15 ) * - 10 /
/
) " ;
auto schedule = make_schedule ( deck_string ) ;
UDQState udq_state ( 0 ) ;
2021-02-28 10:04:35 -06:00
SummaryState st ( TimeService : : now ( ) ) ;
2020-11-05 08:35:55 -06:00
const auto & udq = schedule . getUDQConfig ( 0 ) ;
2023-01-19 06:20:52 -06:00
auto segmentMatcherFactory = [ ] ( ) { return std : : make_unique < SegmentMatcher > ( ScheduleState { } ) ; } ;
udq . eval ( 0 , schedule , schedule . wellMatcher ( 0 ) , segmentMatcherFactory , st , udq_state ) ;
2020-11-05 08:35:55 -06:00
auto fu_var1 = st . get ( " FU_VAR1 " ) ;
auto fu_var2 = st . get ( " FU_VAR2 " ) ;
auto fu_var3 = st . get ( " FU_VAR3 " ) ;
auto fu_var4 = st . get ( " FU_VAR4 " ) ;
BOOST_CHECK_EQUAL ( fu_var1 , - 50 ) ;
BOOST_CHECK_EQUAL ( fu_var2 , - 50 ) ;
BOOST_CHECK_EQUAL ( fu_var3 , 50 ) ;
BOOST_CHECK_EQUAL ( fu_var4 , 50 ) ;
}
2020-11-15 03:03:34 -06:00
BOOST_AUTO_TEST_CASE ( UDQ_UPDATE ) {
std : : string invalid1 = R " (
SCHEDULE
UDQ
UPDATE FU_XXX /
/
) " ;
std : : string valid = R " (
SCHEDULE
UDQ
DEFINE FU_TIME TIME /
/
TSTEP
1 /
UDQ
UPDATE FU_TIME OFF /
/
TSTEP
1 /
TSTEP
1 /
UDQ
UPDATE FU_TIME NEXT /
/
TSTEP
1 /
TSTEP
1 /
UDQ
UPDATE FU_TIME OFF /
/
TSTEP
1 /
) " ;
BOOST_CHECK_THROW ( make_schedule ( invalid1 ) , std : : exception ) ;
auto schedule = make_schedule ( valid ) ;
UDQState udq_state ( 0 ) ;
2021-02-28 10:04:35 -06:00
SummaryState st ( TimeService : : now ( ) ) ;
2020-11-15 03:03:34 -06:00
UDQSet result = UDQSet : : scalar ( " RES " , 0 ) ;
{
const auto & udq = schedule . getUDQConfig ( 0 ) ;
const auto & def = udq . define ( " FU_TIME " ) ;
BOOST_CHECK ( udq_state . define ( def . keyword ( ) , def . status ( ) ) ) ;
udq_state . add_define ( 0 , def . keyword ( ) , result ) ;
}
{
const auto & udq = schedule . getUDQConfig ( 1 ) ;
const auto & def = udq . define ( " FU_TIME " ) ;
BOOST_CHECK ( ! udq_state . define ( def . keyword ( ) , def . status ( ) ) ) ;
}
{
const auto & udq = schedule . getUDQConfig ( 2 ) ;
const auto & def = udq . define ( " FU_TIME " ) ;
BOOST_CHECK ( ! udq_state . define ( def . keyword ( ) , def . status ( ) ) ) ;
}
{
const auto & udq = schedule . getUDQConfig ( 3 ) ;
const auto & def = udq . define ( " FU_TIME " ) ;
BOOST_CHECK ( udq_state . define ( def . keyword ( ) , def . status ( ) ) ) ;
udq_state . add_define ( 3 , def . keyword ( ) , result ) ;
}
{
const auto & udq = schedule . getUDQConfig ( 4 ) ;
const auto & def = udq . define ( " FU_TIME " ) ;
BOOST_CHECK ( ! udq_state . define ( def . keyword ( ) , def . status ( ) ) ) ;
}
{
const auto & udq = schedule . getUDQConfig ( 5 ) ;
const auto & def = udq . define ( " FU_TIME " ) ;
BOOST_CHECK ( ! udq_state . define ( def . keyword ( ) , def . status ( ) ) ) ;
}
}
2020-11-21 06:36:56 -06:00
BOOST_AUTO_TEST_CASE ( UDQ_TYPE_CAST ) {
std : : string valid = R " (
SCHEDULE
UDQ
ASSIGN FUBHPP1 100 /
/
TSTEP
10 /
UDQ
DEFINE FU_TIME TIME /
DEFINE WUDELTA WBHP ' * ' - FUBHPP1 /
DEFINE WU_TEST WUBHPINI ' * ' - ( WGPR ' * ' ) / 2000.0 /
/
) " ;
auto schedule = make_schedule ( valid ) ;
UDQState udq_state ( 0 ) ;
2021-02-28 10:04:35 -06:00
SummaryState st ( TimeService : : now ( ) ) ;
2020-11-21 06:36:56 -06:00
UDQFunctionTable udqft ;
2023-01-10 03:44:15 -06:00
WellMatcher wm ( NameOrder ( { " W1 " , " W2 " , " W3 " } ) ) ;
2023-01-19 06:20:52 -06:00
auto segmentMatcherFactory = [ ] ( ) { return std : : make_unique < SegmentMatcher > ( ScheduleState { } ) ; } ;
2023-10-23 08:07:23 -05:00
UDQContext context ( udqft , wm , { } , segmentMatcherFactory , st , udq_state ) ;
2020-11-21 06:36:56 -06:00
st . update_well_var ( " W1 " , " WBHP " , 400 ) ;
st . update_well_var ( " W2 " , " WBHP " , 300 ) ;
st . update_well_var ( " W3 " , " WBHP " , 200 ) ;
const auto & udq = schedule . getUDQConfig ( 1 ) ;
{
const auto & ass = udq . assign ( " FUBHPP1 " ) ;
2023-06-28 06:13:53 -05:00
context . update_assign ( " FUBHPP1 " , ass . eval ( ) ) ;
2020-11-21 06:36:56 -06:00
}
const auto & def = udq . define ( " WUDELTA " ) ;
auto res = def . eval ( context ) ;
BOOST_CHECK_EQUAL ( res [ " W1 " ] . get ( ) , 300 ) ;
BOOST_CHECK_EQUAL ( res [ " W2 " ] . get ( ) , 200 ) ;
BOOST_CHECK_EQUAL ( res [ " W3 " ] . get ( ) , 100 ) ;
}
2021-06-24 09:46:53 -05:00
2021-09-11 01:29:42 -05:00
BOOST_AUTO_TEST_CASE ( UDQ_TRAILING_COMMENT ) {
std : : string valid = R " (
SCHEDULE
UDQ
ASSIGN FUBHPP1 100 /
/ Comment here
) " ;
BOOST_CHECK_NO_THROW ( make_schedule ( valid ) ) ;
}
2021-06-24 09:46:53 -05:00
BOOST_AUTO_TEST_CASE ( UDQ_ASSIGN_RST ) {
std : : unordered_set < std : : string > selector { " W1 " , " W2 " } ;
UDQAssign assign ( " WUBHP " , selector , 100 , 2 ) ;
auto res = assign . eval ( { " W1 " , " W2 " , " W3 " } ) ;
BOOST_CHECK_EQUAL ( res . size ( ) , 3 ) ;
BOOST_CHECK_EQUAL ( res [ " W1 " ] . get ( ) , 100 ) ;
BOOST_CHECK_EQUAL ( res [ " W2 " ] . get ( ) , 100 ) ;
BOOST_CHECK_EQUAL ( res [ " W3 " ] . defined ( ) , false ) ;
}
2023-01-31 12:15:55 -06:00
BOOST_AUTO_TEST_CASE ( UDQ_ASSIGN_SEGMENT )
{
auto segmentMatcherFactory = [ sched_state = dynamicInputData ( ) ] ( )
{
return std : : make_unique < SegmentMatcher > ( sched_state ) ;
} ;
auto cfg = UDQConfig { } ;
cfg . add_assign ( " SUSPECT " , segmentMatcherFactory , { " OP-01 " } , 17.29 , 42 ) ;
cfg . add_assign ( " SUSPECT " , segmentMatcherFactory , { " OP-02 " , " 3 " } , 9.876e-5 , 42 ) ;
cfg . add_assign ( " SUSPECT " , segmentMatcherFactory , { " OP-06 " , " 1 " } , 0.123 , 42 ) ; // Not an MSW
cfg . add_assign ( " SUPER " , segmentMatcherFactory , { } , 2.71828 , 42 ) ;
cfg . add_assign ( " SUCCINCT " , segmentMatcherFactory , { " OP* " , " 2 " } , 3.1415 , 42 ) ;
{
const auto all = cfg . assignments ( ) ;
BOOST_CHECK_EQUAL ( all . size ( ) , std : : size_t { 3 } ) ; // Three different SU* variables
}
}
2023-10-11 08:01:08 -05:00
BOOST_AUTO_TEST_CASE ( UDQ_Update_SummaryState )
{
auto st = SummaryState { TimeService : : now ( ) } ;
// P2 not yet online
st . update_well_var ( " P1 " , " WBHP " , 42.0 ) ;
st . update_well_var ( " P2 " , " WBHP " , 0.0 ) ;
st . update_well_var ( " P3 " , " WBHP " , 121.2 ) ;
// BB not yet online
st . update_group_var ( " G1 " , " GOPR " , 1222.0 ) ;
st . update_group_var ( " BB " , " GOPR " , 0.0 ) ;
st . update_group_var ( " AA " , " GOPR " , 1234.5 ) ;
// P2 not yet online
st . update_udq ( UDQSet : : wells ( " WUBAR " , { " P1 " , " P3 " } , 17.29 ) , - 123.4 ) ;
BOOST_CHECK_CLOSE ( st . get_well_var ( " P1 " , " WUBAR " ) , 17.29 , 1.0e-8 ) ;
BOOST_CHECK_CLOSE ( st . get_well_var ( " P2 " , " WUBAR " ) , - 123.4 , 1.0e-8 ) ;
BOOST_CHECK_CLOSE ( st . get_well_var ( " P3 " , " WUBAR " ) , 17.29 , 1.0e-8 ) ;
// BB not yet online
st . update_udq ( UDQSet : : groups ( " GUNDA_ST " , { " G1 " , " AA " } , 652.44 ) , - 123.4 ) ;
BOOST_CHECK_CLOSE ( st . get_group_var ( " AA " , " GUNDA_ST " ) , 652.44 , 1.0e-8 ) ;
BOOST_CHECK_CLOSE ( st . get_group_var ( " BB " , " GUNDA_ST " ) , - 123.4 , 1.0e-8 ) ;
BOOST_CHECK_CLOSE ( st . get_group_var ( " G1 " , " GUNDA_ST " ) , 652.44 , 1.0e-8 ) ;
}
2023-10-24 01:21:00 -05:00
BOOST_AUTO_TEST_CASE ( UDQ_WITH_UDT_FIELD )
{
std : : string valid = R " (
SCHEDULE
UDT
' TU_FBHP ' 1 /
' LC ' 100.0 500.0 / - - FOPR values
100.0 180.0 / - - FBHP values
/
/
UDQ
ASSIGN FU_FOPR 110.0 /
ASSIGN FU_WBHP 0 /
DEFINE FU_WBHP0 FU_WBHP /
DEFINE FU_WBHP TU_FBHP [ FU_FOPR ] UMIN FU_WBHP0 /
/
) " ;
auto schedule = make_schedule ( valid ) ;
UDQState udq_state ( 0 ) ;
SummaryState st ( TimeService : : now ( ) ) ;
UDQFunctionTable udqft ;
WellMatcher wm ( NameOrder ( { " W1 " , " W2 " , " W3 " } ) ) ;
const auto & udq = schedule . getUDQConfig ( 0 ) ;
auto segmentMatcherFactory = [ ] ( ) { return std : : make_unique < SegmentMatcher > ( ScheduleState { } ) ; } ;
UDQContext context ( udqft , wm , udq . tables ( ) , segmentMatcherFactory , st , udq_state ) ;
const auto & ass = udq . assign ( " FU_WBHP " ) ;
context . update_assign ( " FU_WBHP " , ass . eval ( ) ) ;
const auto & ass2 = udq . assign ( " FU_FOPR " ) ;
context . update_assign ( " FU_FOPR " , ass2 . eval ( ) ) ;
udq . define ( " FU_WBHP0 " ) ;
const auto & def = udq . define ( " FU_WBHP " ) ;
auto res = def . eval ( context ) ;
BOOST_CHECK_EQUAL ( res . size ( ) , 1U ) ;
BOOST_CHECK_EQUAL ( res [ 0 ] . get ( ) , 100.0 + ( 180.0 - 100.0 ) * ( 110.0 - 100.0 ) / ( 500.0 - 100.0 ) ) ;
}
BOOST_AUTO_TEST_CASE ( UDQ_WITH_UDT_WELL )
{
std : : string valid = R " (
SCHEDULE
WELSPECS
' PROD1 ' ' TEST ' 5 1 1 * ' OIL ' 2 * ' STOP ' 4 * /
' PROD2 ' ' TEST ' 1 1 1 * ' OIL ' 2 * ' STOP ' 4 * /
/
UDT
' TU_FBHP ' 1 /
' LC ' 100.0 500.0 / - - FOPR values
100.0 180.0 / - - FBHP values
/
/
UDQ
ASSIGN WU_WBHP 0 /
DEFINE WU_WBHP0 FU_WBHP /
DEFINE WU_WBHP TU_FBHP [ WOPR ] UMIN WU_WBHP0 /
/
) " ;
auto schedule = make_schedule ( valid ) ;
UDQState udq_state ( 0 ) ;
SummaryState st ( TimeService : : now ( ) ) ;
UDQFunctionTable udqft ;
WellMatcher wm ( NameOrder ( { " PROD1 " , " PROD2 " } ) ) ;
const auto & udq = schedule . getUDQConfig ( 0 ) ;
st . update_well_var ( " PROD1 " , " WOPR " , 120.0 ) ;
st . update_well_var ( " PROD2 " , " WOPR " , 450.0 ) ;
auto segmentMatcherFactory = [ ] ( ) { return std : : make_unique < SegmentMatcher > ( ScheduleState { } ) ; } ;
udq . eval ( 0 , schedule , wm , segmentMatcherFactory , st , udq_state ) ;
const double wu_wbhp1 = st . get_well_var ( " PROD1 " , " WU_WBHP " ) ;
const double wu_wbhp2 = st . get_well_var ( " PROD2 " , " WU_WBHP " ) ;
BOOST_CHECK_EQUAL ( wu_wbhp1 , 100.0 + ( 180.0 - 100.0 ) * ( 120.0 - 100.0 ) / ( 500.0 - 100.0 ) ) ;
BOOST_CHECK_EQUAL ( wu_wbhp2 , 100.0 + ( 180.0 - 100.0 ) * ( 450.0 - 100.0 ) / ( 500.0 - 100.0 ) ) ;
}