COMPDAT I/J can be defaulted

According to the manual, defaulting or putting 0 for I and J coordinates
will default to the well head I/J.
This commit is contained in:
Jørgen Kvalsvik 2016-07-14 14:46:19 +02:00
parent df9d3c660f
commit 4635318e8f
6 changed files with 129 additions and 150 deletions

View File

@ -17,6 +17,7 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>. along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <algorithm>
#include <cassert> #include <cassert>
#include <vector> #include <vector>
@ -25,6 +26,7 @@
#include <opm/parser/eclipse/Deck/DeckRecord.hpp> #include <opm/parser/eclipse/Deck/DeckRecord.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Completion.hpp> #include <opm/parser/eclipse/EclipseState/Schedule/Completion.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.hpp> #include <opm/parser/eclipse/EclipseState/Schedule/ScheduleEnums.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well.hpp>
#include <opm/parser/eclipse/EclipseState/Util/Value.hpp> #include <opm/parser/eclipse/EclipseState/Util/Value.hpp>
namespace Opm { namespace Opm {
@ -136,12 +138,22 @@ namespace Opm {
disentangled, and each completion is returned separately. disentangled, and each completion is returned separately.
*/ */
std::pair<std::string , std::vector<CompletionPtr> > Completion::completionsFromCOMPDATRecord( const DeckRecord& compdatRecord ) { inline std::vector< CompletionPtr >
fromCOMPDAT( const DeckRecord& compdatRecord, const Well& well ) {
std::vector<CompletionPtr> completions; std::vector<CompletionPtr> completions;
std::string well = compdatRecord.getItem("WELL").getTrimmedString(0);
// We change from eclipse's 1 - n, to a 0 - n-1 solution // We change from eclipse's 1 - n, to a 0 - n-1 solution
int I = compdatRecord.getItem("I").get< int >(0) - 1; // I and J can be defaulted with 0 or *, in which case they are fetched
int J = compdatRecord.getItem("J").get< int >(0) - 1; // from the well head
const auto& itemI = compdatRecord.getItem( "I" );
const auto defaulted_I = itemI.defaultApplied( 0 ) || itemI.get< int >( 0 ) == 0;
const int I = !defaulted_I ? itemI.get< int >( 0 ) - 1 : well.getHeadI();
const auto& itemJ = compdatRecord.getItem( "J" );
const auto defaulted_J = itemJ.defaultApplied( 0 ) || itemJ.get< int >( 0 ) == 0;
const int J = !defaulted_J ? itemJ.get< int >( 0 ) - 1 : well.getHeadJ();
int K1 = compdatRecord.getItem("K1").get< int >(0) - 1; int K1 = compdatRecord.getItem("K1").get< int >(0) - 1;
int K2 = compdatRecord.getItem("K2").get< int >(0) - 1; int K2 = compdatRecord.getItem("K2").get< int >(0) - 1;
WellCompletion::StateEnum state = WellCompletion::StateEnumFromString( compdatRecord.getItem("STATE").getTrimmedString(0) ); WellCompletion::StateEnum state = WellCompletion::StateEnumFromString( compdatRecord.getItem("STATE").getTrimmedString(0) );
@ -171,7 +183,7 @@ namespace Opm {
completions.push_back( completion ); completions.push_back( completion );
} }
return std::pair<std::string , std::vector<CompletionPtr> >( well , completions ); return completions;
} }
/* /*
@ -184,25 +196,31 @@ namespace Opm {
} }
*/ */
std::map< std::string, std::vector< CompletionPtr > >
Completion::fromCOMPDAT( const DeckKeyword& compdatKeyword,
const std::vector< const Well* >& wells ) {
std::map<std::string , std::vector< CompletionPtr> > Completion::completionsFromCOMPDATKeyword( const DeckKeyword& compdatKeyword ) { std::map< std::string, std::vector< CompletionPtr > > res;
std::map<std::string , std::vector< CompletionPtr> > completionMapList;
for (size_t recordIndex = 0; recordIndex < compdatKeyword.size(); recordIndex++) {
std::pair<std::string , std::vector< CompletionPtr> > wellCompletionsPair = completionsFromCOMPDATRecord( compdatKeyword.getRecord( recordIndex ));
std::string well = wellCompletionsPair.first;
std::vector<CompletionPtr>& newCompletions = wellCompletionsPair.second;
if (completionMapList.find(well) == completionMapList.end()) for( const auto& record : compdatKeyword ) {
completionMapList[well] = std::vector<CompletionPtr>();
{ const auto wellname = record.getItem( "WELL" ).getTrimmedString( 0 );
std::vector<CompletionPtr>& currentCompletions = completionMapList.find(well)->second; const auto name_eq = [&]( const Well* w ) {
return w->name() == wellname;
};
for (size_t ic = 0; ic < newCompletions.size(); ic++) auto well = std::find_if( wells.begin(), wells.end(), name_eq );
currentCompletions.push_back( newCompletions[ic] );
} if( well == wells.end() ) continue;
auto completions = Opm::fromCOMPDAT( record, **well );
res[ wellname ].insert( res[ wellname ].end(),
completions.begin(),
completions.end() );
} }
return completionMapList;
return res;
} }
void Completion::fixDefaultIJ(int wellHeadI , int wellHeadJ) { void Completion::fixDefaultIJ(int wellHeadI , int wellHeadJ) {

View File

@ -34,6 +34,7 @@ namespace Opm {
class DeckKeyword; class DeckKeyword;
class DeckRecord; class DeckRecord;
class Well;
class Completion { class Completion {
public: public:
@ -67,8 +68,9 @@ namespace Opm {
WellCompletion::DirectionEnum getDirection() const; WellCompletion::DirectionEnum getDirection() const;
static std::map<std::string , std::vector<std::shared_ptr<Completion> > > completionsFromCOMPDATKeyword( const DeckKeyword& compdatKeyword ); static std::map< std::string, std::vector< std::shared_ptr< Completion > > >
static std::pair<std::string , std::vector<std::shared_ptr<Completion> > > completionsFromCOMPDATRecord( const DeckRecord& compdatRecord ); fromCOMPDAT( const DeckKeyword& compdatKeyword,
const std::vector< const Well* >& );
private: private:
int m_i, m_j, m_k; int m_i, m_j, m_k;

View File

@ -1118,13 +1118,12 @@ namespace Opm {
void Schedule::handleCOMPDAT( const DeckKeyword& keyword, size_t currentStep) { void Schedule::handleCOMPDAT( const DeckKeyword& keyword, size_t currentStep) {
std::map<std::string , std::vector< CompletionPtr> > completionMapList = Completion::completionsFromCOMPDATKeyword( keyword ); const auto wells = this->getWells( currentStep );
std::map<std::string , std::vector< CompletionPtr> >::iterator iter; auto completions = Completion::fromCOMPDAT( keyword, wells );
for( const auto pair : completions )
m_wells.get( pair.first )->addCompletions( currentStep, pair.second );
for( iter= completionMapList.begin(); iter != completionMapList.end(); iter++) {
const std::string wellName = iter->first;
m_wells.get( wellName )->addCompletions(currentStep, iter->second);
}
m_events->addEvent(ScheduleEvents::COMPLETION_CHANGE, currentStep); m_events->addEvent(ScheduleEvents::COMPLETION_CHANGE, currentStep);
} }

View File

@ -187,8 +187,8 @@ static DeckPtr createDeckWithWellsAndCompletionData() {
" 10 JUL 2007 / \n" " 10 JUL 2007 / \n"
" 10 AUG 2007 / \n" " 10 AUG 2007 / \n"
"/\n" "/\n"
"COMPDAT\n" "COMPDAT\n" // with defaulted I and J
" 'OP_1' 9 9 3 9 'OPEN' 1* 32.948 0.311 3047.839 1* 1* 'X' 22.100 / \n" " 'OP_1' 0 * 3 9 'OPEN' 1* 32.948 0.311 3047.839 1* 1* 'X' 22.100 / \n"
"/\n"; "/\n";
return parser.parseString(input, ParseContext()); return parser.parseString(input, ParseContext());

View File

@ -19,84 +19,30 @@
#define BOOST_TEST_MODULE CompletionIntegrationTests #define BOOST_TEST_MODULE CompletionIntegrationTests
#include <map>
#include <stdexcept>
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/filesystem/path.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp> #include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Deck/DeckRecord.hpp> #include <opm/parser/eclipse/Deck/DeckRecord.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
#include <opm/parser/eclipse/Parser/Parser.hpp> #include <opm/parser/eclipse/Parser/Parser.hpp>
#include <opm/parser/eclipse/Parser/ParseContext.hpp> #include <opm/parser/eclipse/Parser/ParseContext.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp> #include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Completion.hpp> #include <opm/parser/eclipse/EclipseState/Schedule/Completion.hpp>
using namespace Opm; using namespace Opm;
BOOST_AUTO_TEST_CASE( CreateCompletionsFromRecord ) {
ParserPtr parser(new Parser());
boost::filesystem::path scheduleFile("testdata/integration_tests/SCHEDULE/SCHEDULE_COMPDAT1");
DeckPtr deck = parser->parseFile(scheduleFile.string(), ParseContext());
const auto& COMPDAT1 = deck->getKeyword("COMPDAT" , 0);
const auto& line0 = COMPDAT1.getRecord(0);
const auto& line1 = COMPDAT1.getRecord(1);
std::pair< std::string , std::vector<CompletionPtr> > completionsList = Completion::completionsFromCOMPDATRecord( line0 );
BOOST_CHECK_EQUAL( "W_1" , completionsList.first );
BOOST_CHECK_EQUAL( 3U , completionsList.second.size() );
{
CompletionPtr completion0 = completionsList.second[0];
CompletionPtr completion2 = completionsList.second[2];
BOOST_CHECK_EQUAL( 29 , completion0->getI() );
BOOST_CHECK_EQUAL( 36 , completion0->getJ() );
BOOST_CHECK_EQUAL( 0 , completion0->getK() );
BOOST_CHECK_EQUAL( WellCompletion::OPEN , completion0->getState() );
BOOST_CHECK_EQUAL( 3.8134259259259256e-12 , completion0->getConnectionTransmissibilityFactor() );
BOOST_CHECK_EQUAL( WellCompletion::DirectionEnum::X, completion0->getDirection() );
BOOST_CHECK_EQUAL( 29 , completion2->getI() );
BOOST_CHECK_EQUAL( 36 , completion2->getJ() );
BOOST_CHECK_EQUAL( 2 , completion2->getK() );
BOOST_CHECK_EQUAL( WellCompletion::OPEN , completion2->getState() );
BOOST_CHECK_EQUAL( 3.8134259259259256e-12 , completion2->getConnectionTransmissibilityFactor() );
BOOST_CHECK_EQUAL( WellCompletion::DirectionEnum::X, completion2->getDirection() );
}
{
std::pair<std::string , std::vector<CompletionPtr> > pair = Completion::completionsFromCOMPDATRecord( line1 );
// We try to get the numerical value of a default CF:
CompletionPtr comp = pair.second[0];
/*
This statement gives a compilation error:
BOOST_CHECK_THROW( comp->getConnectionTransmissibilityFactor() , std::logical_error );
*/
}
}
BOOST_AUTO_TEST_CASE( CreateCompletionsFromKeyword ) { BOOST_AUTO_TEST_CASE( CreateCompletionsFromKeyword ) {
ParserPtr parser(new Parser()); ParserPtr parser(new Parser());
boost::filesystem::path scheduleFile("testdata/integration_tests/SCHEDULE/SCHEDULE_COMPDAT1"); const auto scheduleFile = "testdata/integration_tests/SCHEDULE/SCHEDULE_COMPDAT1";
DeckPtr deck = parser->parseFile(scheduleFile.string(), ParseContext()); DeckPtr deck = parser->parseFile(scheduleFile, ParseContext());
const auto grid = std::make_shared< const EclipseGrid >( *deck );
const Schedule schedule( ParseContext(), grid, *deck );
const auto& COMPDAT1 = deck->getKeyword("COMPDAT" , 1); const auto& COMPDAT1 = deck->getKeyword("COMPDAT" , 1);
std::map< std::string , std::vector<CompletionPtr> > completions = Completion::completionsFromCOMPDATKeyword( COMPDAT1 ); const auto wells = schedule.getWells( 0 );
auto completions = Completion::fromCOMPDAT( COMPDAT1, wells );
BOOST_CHECK_EQUAL( 3U , completions.size() ); BOOST_CHECK_EQUAL( 3U , completions.size() );
BOOST_CHECK( completions.find("W_1") != completions.end() ); BOOST_CHECK( completions.find("W_1") != completions.end() );
BOOST_CHECK( completions.find("W_2") != completions.end() ); BOOST_CHECK( completions.find("W_2") != completions.end() );
BOOST_CHECK( completions.find("W_3") != completions.end() ); BOOST_CHECK( completions.find("W_3") != completions.end() );
@ -110,19 +56,17 @@ BOOST_AUTO_TEST_CASE( CreateCompletionsFromKeyword ) {
CompletionConstPtr completion0 = W_3Completions[0]; CompletionConstPtr completion0 = W_3Completions[0];
CompletionConstPtr completion4 = W_3Completions[4]; CompletionConstPtr completion4 = W_3Completions[4];
BOOST_CHECK_EQUAL( 30 , completion0->getI() ); BOOST_CHECK_EQUAL( 2 , completion0->getI() );
BOOST_CHECK_EQUAL( 17 , completion0->getJ() ); BOOST_CHECK_EQUAL( 7 , completion0->getJ() );
BOOST_CHECK_EQUAL( 0 , completion0->getK() ); BOOST_CHECK_EQUAL( 0 , completion0->getK() );
BOOST_CHECK_EQUAL( WellCompletion::OPEN , completion0->getState() ); BOOST_CHECK_EQUAL( WellCompletion::OPEN , completion0->getState() );
BOOST_CHECK_EQUAL( 3.1726851851851847e-12 , completion0->getConnectionTransmissibilityFactor() ); BOOST_CHECK_EQUAL( 3.1726851851851847e-12 , completion0->getConnectionTransmissibilityFactor() );
BOOST_CHECK_EQUAL( WellCompletion::DirectionEnum::Y, completion0->getDirection() ); BOOST_CHECK_EQUAL( WellCompletion::DirectionEnum::Y, completion0->getDirection() );
BOOST_CHECK_EQUAL( 30 , completion4->getI() ); BOOST_CHECK_EQUAL( 2 , completion4->getI() );
BOOST_CHECK_EQUAL( 16 , completion4->getJ() ); BOOST_CHECK_EQUAL( 6 , completion4->getJ() );
BOOST_CHECK_EQUAL( 3 , completion4->getK() ); BOOST_CHECK_EQUAL( 3 , completion4->getK() );
BOOST_CHECK_EQUAL( WellCompletion::OPEN , completion4->getState() ); BOOST_CHECK_EQUAL( WellCompletion::OPEN , completion4->getState() );
BOOST_CHECK_EQUAL( 5.4722222222222212e-13 , completion4->getConnectionTransmissibilityFactor() ); BOOST_CHECK_EQUAL( 5.4722222222222212e-13 , completion4->getConnectionTransmissibilityFactor() );
BOOST_CHECK_EQUAL( WellCompletion::DirectionEnum::Y, completion4->getDirection() ); BOOST_CHECK_EQUAL( WellCompletion::DirectionEnum::Y, completion4->getDirection() );
} }

View File

@ -1,67 +1,83 @@
DIMENS
10 10 10 /
GRID
DX
1000*1 /
DY
1000*1 /
DZ
1000*1 /
TOPS
1000*1 /
SCHEDULE
WELSPECS WELSPECS
'W_1' 'OP' 30 37 3.33 'OIL' 7* / 'W_1' 'OP' 3 7 3.33 'OIL' 7* /
'W_2' 'OP' 30 37 3.33 'OIL' 7* / 'W_2' 'OP' 3 7 3.33 'OIL' 7* /
'W_3' 'OP' 30 37 3.33 'OIL' 7* / 'W_3' 'OP' 3 7 3.33 'OIL' 7* /
/ /
COMPDAT COMPDAT
-- WELL I J K1 K2 Sat. CF DIAM KH SKIN ND DIR Ro -- WELL I J K1 K2 Sat. CF DIAM KH SKIN ND DIR Ro
'W_1' 30 37 1 3 'OPEN' 1* 32.948 0.311 3047.839 2* 'X' 22.100 / 'W_1' 3 3 1 3 'OPEN' 1* 32.948 0.311 3047.839 2* 'X' 22.100 /
'W_1' 30 37 2 2 'OPEN' 1* * 0.311 4332.346 2* 'X' 22.123 / 'W_1' 3 3 2 2 'OPEN' 1* * 0.311 4332.346 2* 'X' 22.123 /
'W_1' 30 37 3 3 'OPEN' 1* 51.867 0.311 4799.764 2* 'X' 22.143 / 'W_1' 3 3 3 3 'OPEN' 1* 51.867 0.311 4799.764 2* 'X' 22.143 /
'W_1' 30 37 4 4 'OPEN' 1* 34.243 0.311 3169.482 2* 'X' 22.166 / 'W_1' 3 3 4 4 'OPEN' 1* 34.243 0.311 3169.482 2* 'X' 22.166 /
'W_1' 31 37 4 4 'OPEN' 1* 8.988 0.311 832.457 2* 'X' 22.236 / 'W_1' 3 3 4 4 'OPEN' 1* 8.988 0.311 832.457 2* 'X' 22.236 /
'W_1' 31 37 5 5 'OPEN' 1* 36.435 0.311 3375.309 2* 'X' 22.262 / 'W_1' 3 3 5 5 'OPEN' 1* 36.435 0.311 3375.309 2* 'X' 22.262 /
'W_1' 31 37 6 6 'OPEN' 1* 39.630 0.311 3672.067 2* 'X' 22.283 / 'W_1' 3 3 6 6 'OPEN' 1* 39.630 0.311 3672.067 2* 'X' 22.283 /
'W_1' 31 37 7 7 'OPEN' 1* 33.975 0.311 3148.671 2* 'X' 22.307 / 'W_1' 3 3 7 7 'OPEN' 1* 33.975 0.311 3148.671 2* 'X' 22.307 /
'W_1' 31 37 8 8 'OPEN' 1* 24.869 0.311 2305.242 2* 'X' 22.329 / 'W_1' 3 3 8 8 'OPEN' 1* 24.869 0.311 2305.242 2* 'X' 22.329 /
'W_1' 31 37 9 9 'OPEN' 1* 38.301 0.311 3551.043 2* 'X' 22.351 / 'W_1' 3 3 9 9 'OPEN' 1* 38.301 0.311 3551.043 2* 'X' 22.351 /
'W_1' 31 37 10 10 'OPEN' 1* 6.642 0.311 615.914 2* 'X' 22.372 / 'W_1' 3 3 1 1 'OPEN' 1* 6.642 0.311 615.914 2* 'X' 22.372 /
'W_1' 31 37 11 11 'OPEN' 1* 1.322 0.311 122.614 2* 'X' 22.396 / 'W_1' 3 3 1 1 'OPEN' 1* 1.322 0.311 122.614 2* 'X' 22.396 /
'W_1' 31 37 12 12 'OPEN' 1* 3.797 0.311 352.293 2* 'X' 22.418 / 'W_1' 3 3 1 1 'OPEN' 1* 3.797 0.311 352.293 2* 'X' 22.418 /
'W_1' 31 37 13 13 'OPEN' 1* 14.742 0.311 1367.872 2* 'X' 22.439 / 'W_1' 3 3 1 1 'OPEN' 1* 14.742 0.311 1367.872 2* 'X' 22.439 /
'W_1' 31 37 14 14 'OPEN' 1* 19.731 0.311 1831.202 2* 'X' 22.463 / 'W_1' 3 3 1 1 'OPEN' 1* 19.731 0.311 1831.202 2* 'X' 22.463 /
'W_2' 20 51 1 1 'OPEN' 1* 1.168 0.311 107.872 2* 'Y' 21.925 / 'W_2' 2 5 1 1 'OPEN' 1* 1.168 0.311 107.872 2* 'Y' 21.925 /
'W_2' 20 51 2 2 'OPEN' 1* 15.071 0.311 1391.859 2* 'Y' 21.920 / 'W_2' 2 5 2 2 'OPEN' 1* 15.071 0.311 1391.859 2* 'Y' 21.920 /
'W_2' 20 51 3 3 'OPEN' 1* 6.242 0.311 576.458 2* 'Y' 21.915 / 'W_2' 2 5 3 3 'OPEN' 1* 6.242 0.311 576.458 2* 'Y' 21.915 /
'W_2' 20 51 4 4 'OPEN' 1* 16.493 0.311 1522.982 2* 'Y' 21.908 / 'W_2' 2 5 4 4 'OPEN' 1* 16.493 0.311 1522.982 2* 'Y' 21.908 /
'W_2' 20 51 5 5 'OPEN' 1* 7.359 0.311 679.489 2* 'Y' 21.903 / 'W_2' 2 5 5 5 'OPEN' 1* 7.359 0.311 679.489 2* 'Y' 21.903 /
'W_3' 31 18 1 1 'OPEN' 1* 27.412 0.311 2445.337 2* 'Y' 18.521 / 'W_3' 3 1 1 1 'OPEN' 1* 27.412 0.311 2445.337 2* 'Y' 18.521 /
'W_3' 31 18 2 2 'OPEN' 1* 55.195 0.311 4923.842 2* 'Y' 18.524 / 'W_3' 3 1 2 2 'OPEN' 1* 55.195 0.311 4923.842 2* 'Y' 18.524 /
'W_3' 31 18 3 3 'OPEN' 1* 18.032 0.311 1608.615 2* 'Y' 18.526 / 'W_3' 3 1 3 3 'OPEN' 1* 18.032 0.311 1608.615 2* 'Y' 18.526 /
'W_3' 31 17 3 3 'OPEN' 1* 56.817 0.311 5047.177 2* 'Y' 18.155 / 'W_3' 3 1 3 3 'OPEN' 1* 56.817 0.311 5047.177 2* 'Y' 18.155 /
'W_3' 31 17 4 4 'OPEN' 1* 4.728 0.311 420.067 2* 'Y' 18.162 / 'W_3' 3 1 4 4 'OPEN' 1* 4.728 0.311 420.067 2* 'Y' 18.162 /
/ /
COMPDAT COMPDAT
-- WELL I J K1 K2 Sat. CF DIAM KH SKIN ND DIR Ro -- WELL I J K1 K2 Sat. CF DIAM KH SKIN ND DIR Ro
'W_1' 30 37 1 3 'OPEN' 1* 32.948 0.311 3047.839 2* 'X' 22.100 / 'W_1' 3 7 1 3 'OPEN' 1* 32.948 0.311 3047.839 2* 'X' 22.100 /
'W_1' 30 37 2 2 'OPEN' 1* 23487.0 0.311 4332.346 2* 'X' 22.123 / 'W_1' 3 7 2 2 'OPEN' 1* 23487.0 0.311 4332.346 2* 'X' 22.123 /
'W_1' 30 37 3 3 'OPEN' 1* 51.867 0.311 4799.764 2* 'X' 22.143 / 'W_1' 3 7 3 3 'OPEN' 1* 51.867 0.311 4799.764 2* 'X' 22.143 /
'W_1' 30 37 4 4 'OPEN' 1* 34.243 0.311 3169.482 2* 'X' 22.166 / 'W_1' 3 7 4 4 'OPEN' 1* 34.243 0.311 3169.482 2* 'X' 22.166 /
'W_1' 31 37 4 4 'OPEN' 1* 8.988 0.311 832.457 2* 'X' 22.236 / 'W_1' 3 7 4 4 'OPEN' 1* 8.988 0.311 832.457 2* 'X' 22.236 /
'W_1' 31 37 5 5 'OPEN' 1* 36.435 0.311 3375.309 2* 'X' 22.262 / 'W_1' 3 7 5 5 'OPEN' 1* 36.435 0.311 3375.309 2* 'X' 22.262 /
'W_1' 31 37 6 6 'OPEN' 1* 39.630 0.311 3672.067 2* 'X' 22.283 / 'W_1' 3 7 6 6 'OPEN' 1* 39.630 0.311 3672.067 2* 'X' 22.283 /
'W_1' 31 37 7 7 'OPEN' 1* 33.975 0.311 3148.671 2* 'X' 22.307 / 'W_1' 3 7 7 7 'OPEN' 1* 33.975 0.311 3148.671 2* 'X' 22.307 /
'W_1' 31 37 8 8 'OPEN' 1* 24.869 0.311 2305.242 2* 'X' 22.329 / 'W_1' 3 7 8 8 'OPEN' 1* 24.869 0.311 2305.242 2* 'X' 22.329 /
'W_1' 31 37 9 9 'OPEN' 1* 38.301 0.311 3551.043 2* 'X' 22.351 / 'W_1' 3 7 9 9 'OPEN' 1* 38.301 0.311 3551.043 2* 'X' 22.351 /
'W_1' 31 37 10 10 'OPEN' 1* 6.642 0.311 615.914 2* 'X' 22.372 / 'W_1' 3 7 1 1 'OPEN' 1* 6.642 0.311 615.914 2* 'X' 22.372 /
'W_1' 31 37 11 11 'OPEN' 1* 1.322 0.311 122.614 2* 'X' 22.396 / 'W_1' 3 7 1 1 'OPEN' 1* 1.322 0.311 122.614 2* 'X' 22.396 /
'W_1' 31 37 12 12 'OPEN' 1* 3.797 0.311 352.293 2* 'X' 22.418 / 'W_1' 3 7 1 1 'OPEN' 1* 3.797 0.311 352.293 2* 'X' 22.418 /
'W_1' 31 37 13 13 'OPEN' 1* 14.742 0.311 1367.872 2* 'X' 22.439 / 'W_1' 3 7 1 1 'OPEN' 1* 14.742 0.311 1367.872 2* 'X' 22.439 /
'W_1' 31 37 14 14 'OPEN' 1* 19.731 0.311 1831.202 2* 'X' 22.463 / 'W_1' 3 7 1 1 'OPEN' 1* 19.731 0.311 1831.202 2* 'X' 22.463 /
'W_2' 20 51 1 1 'OPEN' 1* 1.168 0.311 107.872 2* 'Y' 21.925 / 'W_2' 2 1 1 1 'OPEN' 1* 1.168 0.311 107.872 2* 'Y' 21.925 /
'W_2' 20 51 2 2 'OPEN' 1* 15.071 0.311 1391.859 2* 'Y' 21.920 / 'W_2' 2 1 2 2 'OPEN' 1* 15.071 0.311 1391.859 2* 'Y' 21.920 /
'W_2' 20 51 3 3 'OPEN' 1* 6.242 0.311 576.458 2* 'Y' 21.915 / 'W_2' 2 1 3 3 'OPEN' 1* 6.242 0.311 576.458 2* 'Y' 21.915 /
'W_2' 20 51 4 4 'OPEN' 1* 16.493 0.311 1522.982 2* 'Y' 21.908 / 'W_2' 2 1 4 4 'OPEN' 1* 16.493 0.311 1522.982 2* 'Y' 21.908 /
'W_2' 20 51 5 5 'OPEN' 1* 7.359 0.311 679.489 2* 'Y' 21.903 / 'W_2' 2 1 5 5 'OPEN' 1* 7.359 0.311 679.489 2* 'Y' 21.903 /
'W_3' 31 18 1 1 'OPEN' 1* 27.412 0.311 2445.337 2* 'Y' 18.521 / 'W_3' 3 8 1 1 'OPEN' 1* 27.412 0.311 2445.337 2* 'Y' 18.521 /
'W_3' 31 18 2 2 'OPEN' 1* 55.195 0.311 4923.842 2* 'Y' 18.524 / 'W_3' 3 8 2 2 'OPEN' 1* 55.195 0.311 4923.842 2* 'Y' 18.524 /
'W_3' 31 18 3 3 'OPEN' 1* 18.032 0.311 1608.615 2* 'Y' 18.526 / 'W_3' 3 8 3 3 'OPEN' 1* 18.032 0.311 1608.615 2* 'Y' 18.526 /
'W_3' 31 17 3 3 'OPEN' 1* 56.817 0.311 5047.177 2* 'Y' 18.155 / 'W_3' 3 7 3 3 'OPEN' 1* 56.817 0.311 5047.177 2* 'Y' 18.155 /
'W_3' 31 17 4 4 'OPEN' 1* 4.728 1* 420.067 2* 'Y' 18.162 / 'W_3' 3 7 4 4 'OPEN' 1* 4.728 1* 420.067 2* 'Y' 18.162 /
/ /