/* Copyright 2013 Statoil ASA. This file is part of the Open Porous Media project (OPM). OPM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OPM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OPM. If not, see . */ #include #include #include #include #include #include #include #include #include #include namespace Opm { EclipseState::EclipseState(DeckConstPtr deck, bool beStrict) { m_deckUnitSystem = deck->getActiveUnitSystem(); if (beStrict) { // make sure all mandatory sections are present and that their order is correct std::ostringstream oss; if (!Section::checkSectionTopology(deck, oss)) throw std::invalid_argument("Section topology of deck is invalid: " + oss.str()); } initPhases(deck); initEclipseGrid(deck); initSchedule(deck); initTitle(deck); initProperties(deck); initTransMult(); initFaults(deck); } std::shared_ptr EclipseState::getDeckUnitSystem() const { return m_deckUnitSystem; } EclipseGridConstPtr EclipseState::getEclipseGrid() const { return m_eclipseGrid; } EclipseGridPtr EclipseState::getEclipseGridCopy() const { return std::make_shared( m_eclipseGrid->c_ptr() ); } ScheduleConstPtr EclipseState::getSchedule() const { return schedule; } std::shared_ptr EclipseState::getFaults() const { return m_faults; } std::shared_ptr EclipseState::getTransMult() const { return m_transMult; } std::string EclipseState::getTitle() const { return m_title; } void EclipseState::initSchedule(DeckConstPtr deck) { schedule = ScheduleConstPtr( new Schedule(deck) ); } void EclipseState::initTransMult() { EclipseGridConstPtr grid = getEclipseGrid(); m_transMult = std::make_shared( grid->getNX() , grid->getNY() , grid->getNZ()); if (hasDoubleGridProperty("MULTX")) m_transMult->applyMULT(getDoubleGridProperty("MULTX"), FaceDir::XPlus); if (hasDoubleGridProperty("MULTX-")) m_transMult->applyMULT(getDoubleGridProperty("MULTX-"), FaceDir::XMinus); if (hasDoubleGridProperty("MULTY")) m_transMult->applyMULT(getDoubleGridProperty("MULTY"), FaceDir::YPlus); if (hasDoubleGridProperty("MULTY-")) m_transMult->applyMULT(getDoubleGridProperty("MULTY-"), FaceDir::YMinus); if (hasDoubleGridProperty("MULTZ")) m_transMult->applyMULT(getDoubleGridProperty("MULTZ"), FaceDir::ZPlus); if (hasDoubleGridProperty("MULTZ-")) m_transMult->applyMULT(getDoubleGridProperty("MULTZ-"), FaceDir::ZMinus); } void EclipseState::initFaults(DeckConstPtr deck) { EclipseGridConstPtr grid = getEclipseGrid(); m_faults = std::make_shared(); std::shared_ptr gridSection(new Opm::GRIDSection(deck) ); for (size_t index=0; index < gridSection->count("FAULTS"); index++) { DeckKeywordConstPtr faultsKeyword = gridSection->getKeyword("FAULTS" , index); for (auto iter = faultsKeyword->begin(); iter != faultsKeyword->end(); ++iter) { DeckRecordConstPtr faultRecord = *iter; const std::string& faultName = faultRecord->getItem(0)->getString(0); int I1 = faultRecord->getItem(1)->getInt(0) - 1; int I2 = faultRecord->getItem(2)->getInt(0) - 1; int J1 = faultRecord->getItem(3)->getInt(0) - 1; int J2 = faultRecord->getItem(4)->getInt(0) - 1; int K1 = faultRecord->getItem(5)->getInt(0) - 1; int K2 = faultRecord->getItem(6)->getInt(0) - 1; FaceDir::DirEnum faceDir = FaceDir::FromString( faultRecord->getItem(7)->getString(0) ); std::shared_ptr face = std::make_shared(grid->getNX() , grid->getNY() , grid->getNZ(), static_cast(I1) , static_cast(I2) , static_cast(J1) , static_cast(J2) , static_cast(K1) , static_cast(K2) , faceDir); if (!m_faults->hasFault(faultName)) { std::shared_ptr fault = std::make_shared( faultName ); m_faults->addFault( fault ); } { std::shared_ptr fault = m_faults->getFault( faultName ); fault->addFace( face ); } } } setMULTFLT( gridSection ); if (Section::hasEDIT(deck)) { std::shared_ptr editSection(new Opm::EDITSection(deck) ); setMULTFLT( editSection ); } m_transMult->applyMULTFLT( m_faults ); } void EclipseState::setMULTFLT(std::shared_ptr section) const { for (size_t index=0; index < section->count("MULTFLT"); index++) { DeckKeywordConstPtr faultsKeyword = section->getKeyword("MULTFLT" , index); for (auto iter = faultsKeyword->begin(); iter != faultsKeyword->end(); ++iter) { DeckRecordConstPtr faultRecord = *iter; const std::string& faultName = faultRecord->getItem(0)->getString(0); double multFlt = faultRecord->getItem(1)->getRawDouble(0); m_faults->setTransMult( faultName , multFlt ); } } } void EclipseState::initEclipseGrid(DeckConstPtr deck) { m_eclipseGrid = EclipseGridConstPtr( new EclipseGrid( deck )); } void EclipseState::initPhases(DeckConstPtr deck) { if (deck->hasKeyword("OIL")) phases.insert(Phase::PhaseEnum::OIL); if (deck->hasKeyword("GAS")) phases.insert(Phase::PhaseEnum::GAS); if (deck->hasKeyword("WATER")) phases.insert(Phase::PhaseEnum::WATER); } bool EclipseState::hasPhase(enum Phase::PhaseEnum phase) const { return (phases.count(phase) == 1); } void EclipseState::initTitle(DeckConstPtr deck){ if (deck->hasKeyword("TITLE")) { DeckKeywordConstPtr titleKeyword = deck->getKeyword("TITLE"); DeckRecordConstPtr record = titleKeyword->getRecord(0); DeckItemPtr item = record->getItem(0); std::vector itemValue = item->getStringData(); m_title = boost::algorithm::join(itemValue, " "); } } bool EclipseState::supportsGridProperty(const std::string& keyword, int enabledTypes) const { bool result = false; if (enabledTypes & IntProperties) result = result || m_intGridProperties->supportsKeyword( keyword ); if (enabledTypes & DoubleProperties) result = result || m_doubleGridProperties->supportsKeyword( keyword ); return result; } bool EclipseState::hasIntGridProperty(const std::string& keyword) const { return m_intGridProperties->hasKeyword( keyword ); } bool EclipseState::hasDoubleGridProperty(const std::string& keyword) const { return m_doubleGridProperties->hasKeyword( keyword ); } /* Observe that this will autocreate a property if it has not been explicitly added. */ std::shared_ptr > EclipseState::getIntGridProperty( const std::string& keyword ) const { return m_intGridProperties->getKeyword( keyword ); } std::shared_ptr > EclipseState::getDoubleGridProperty( const std::string& keyword ) const { return m_doubleGridProperties->getKeyword( keyword ); } void EclipseState::loadGridPropertyFromDeckKeyword(std::shared_ptr inputBox , DeckKeywordConstPtr deckKeyword, int enabledTypes) { const std::string& keyword = deckKeyword->name(); if (m_intGridProperties->supportsKeyword( keyword )) { if (enabledTypes & IntProperties) { auto gridProperty = m_intGridProperties->getKeyword( keyword ); gridProperty->loadFromDeckKeyword( inputBox , deckKeyword ); } } else if (m_doubleGridProperties->supportsKeyword( keyword )) { if (enabledTypes & DoubleProperties) { auto gridProperty = m_doubleGridProperties->getKeyword( keyword ); gridProperty->loadFromDeckKeyword( inputBox , deckKeyword ); } } else { throw std::invalid_argument("Tried to load from unsupported keyword: " + deckKeyword->name()); } } void EclipseState::initProperties(DeckConstPtr deck) { typedef GridProperties::SupportedKeywordInfo SupportedIntKeywordInfo; static std::vector supportedIntKeywords = {SupportedIntKeywordInfo( "SATNUM" , 0 ), SupportedIntKeywordInfo( "PVTNUM" , 0 ), SupportedIntKeywordInfo( "EQLNUM" , 0 ), SupportedIntKeywordInfo( "IMBNUM" , 0 ), // TODO: implement regular expression matching for // keyword names? // SupportedIntKeywordInfo( "FIP???" , 0 ), SupportedIntKeywordInfo( "FIPNUM" , 0 )}; // Note that the variants of grid keywords for radial grids // are not supported. (and hopefully never will be) typedef GridProperties::SupportedKeywordInfo SupportedDoubleKeywordInfo; static std::vector supportedDoubleKeywords = { // keywords to specify the scaled connate gas // saturations. SupportedDoubleKeywordInfo( "SGL" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISGL" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SGLX" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SGLX-" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISGLX" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISGLX-" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SGLY" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SGLY-" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISGLY" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISGLY-" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SGLZ" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SGLZ-" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISGLZ" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISGLZ-" , 0.0, "1" ), // keywords to specify the connate water saturation. SupportedDoubleKeywordInfo( "SWL" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISWL" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SWLX" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SWLX-" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISWLX" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISWLX-" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SWLY" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SWLY-" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISWLY" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISWLY-" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SWLZ" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SWLZ-" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISWLZ" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISWLZ-" , 0.0, "1" ), // keywords to specify the maximum gas saturation. SupportedDoubleKeywordInfo( "SGU" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISGU" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SGUX" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SGUX-" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISGUX" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISGUX-" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SGUY" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SGUY-" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISGUY" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISGUY-" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SGUZ" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SGUZ-" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISGUZ" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISGUZ-" , 0.0, "1" ), // keywords to specify the maximum water saturation. SupportedDoubleKeywordInfo( "SWU" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISWU" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SWUX" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SWUX-" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISWUX" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISWUX-" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SWUY" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SWUY-" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISWUY" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISWUY-" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SWUZ" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SWUZ-" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISWUZ" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISWUZ-" , 0.0, "1" ), // keywords to specify the scaled critical gas // saturation. SupportedDoubleKeywordInfo( "SGCR" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISGCR" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SGCRX" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SGCRX-" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISGCRX" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISGCRX-" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SGCRY" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SGCRY-" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISGCRY" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISGCRY-" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SGCRZ" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SGCRZ-" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISGCRZ" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISGCRZ-" , 0.0, "1" ), // keywords to specify the scaled critical oil-in-water // saturation. SupportedDoubleKeywordInfo( "SOWCR" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISOWCR" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SOWCRX" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SOWCRX-" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISOWCRX" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISOWCRX-" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SOWCRY" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SOWCRY-" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISOWCRY" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISOWCRY-" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SOWCRZ" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SOWCRZ-" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISOWCRZ" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISOWCRZ-" , 0.0, "1" ), // keywords to specify the scaled critical oil-in-gas // saturation. SupportedDoubleKeywordInfo( "SOGCR" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISOGCR" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SOGCRX" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SOGCRX-" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISOGCRX" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISOGCRX-" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SOGCRY" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SOGCRY-" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISOGCRY" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISOGCRY-" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SOGCRZ" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SOGCRZ-" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISOGCRZ" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISOGCRZ-" , 0.0, "1" ), // keywords to specify the scaled critical water // saturation. SupportedDoubleKeywordInfo( "SWCR" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISWCR" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SWCRX" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SWCRX-" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISWCRX" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISWCRX-" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SWCRY" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SWCRY-" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISWCRY" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISWCRY-" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SWCRZ" , 0.0, "1" ), SupportedDoubleKeywordInfo( "SWCRZ-" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISWCRZ" , 0.0, "1" ), SupportedDoubleKeywordInfo( "ISWCRZ-" , 0.0, "1" ), // porosity SupportedDoubleKeywordInfo( "PORO" , 0.0, "1" ), // the permeability keywords SupportedDoubleKeywordInfo( "PERMX" , 0.0, "Permeability" ), SupportedDoubleKeywordInfo( "PERMY" , 0.0, "Permeability" ), SupportedDoubleKeywordInfo( "PERMZ" , 0.0, "Permeability" ), SupportedDoubleKeywordInfo( "PERMXY", 0.0, "Permeability" ), // E300 only SupportedDoubleKeywordInfo( "PERMXZ", 0.0, "Permeability" ), // E300 only SupportedDoubleKeywordInfo( "PERMYZ", 0.0, "Permeability" ), // E300 only // gross-to-net thickness (acts as a multiplier for PORO // and the permeabilities in the X-Y plane as well as for // the well rates.) SupportedDoubleKeywordInfo( "NTG" , 1.0, "1" ), // transmissibility multipliers SupportedDoubleKeywordInfo( "MULTX" , 1.0, "1" ), SupportedDoubleKeywordInfo( "MULTY" , 1.0, "1" ), SupportedDoubleKeywordInfo( "MULTZ" , 1.0, "1" ), SupportedDoubleKeywordInfo( "MULTX-", 1.0, "1" ), SupportedDoubleKeywordInfo( "MULTY-", 1.0, "1" ), SupportedDoubleKeywordInfo( "MULTZ-", 1.0, "1" ), // initialisation SupportedDoubleKeywordInfo( "SWATINIT" , 0.0, "1"), // pore volume multipliers SupportedDoubleKeywordInfo( "MULTPV", 1.0, "1" ) }; // create the grid properties m_intGridProperties = std::make_shared >(m_eclipseGrid->getNX(), m_eclipseGrid->getNY(), m_eclipseGrid->getNZ(), supportedIntKeywords); m_doubleGridProperties = std::make_shared >(m_eclipseGrid->getNX(), m_eclipseGrid->getNY(), m_eclipseGrid->getNZ(), supportedDoubleKeywords); // first process all integer grid properties as these may be needed in order to // initialize the double properties processGridProperties(deck, /*enabledTypes=*/IntProperties); processGridProperties(deck, /*enabledTypes=*/DoubleProperties); } double EclipseState::getSIScaling(const std::string &dimensionString) const { return m_deckUnitSystem->getDimension(dimensionString)->getSIScaling(); } void EclipseState::processGridProperties(Opm::DeckConstPtr deck, int enabledTypes) { if (Section::hasGRID(deck)) { std::shared_ptr gridSection(new Opm::GRIDSection(deck) ); scanSection(gridSection, enabledTypes); } if (Section::hasEDIT(deck)) { std::shared_ptr editSection(new Opm::EDITSection(deck) ); scanSection(editSection, enabledTypes); } if (Section::hasPROPS(deck)) { std::shared_ptr propsSection(new Opm::PROPSSection(deck) ); scanSection(propsSection, enabledTypes); } if (Section::hasREGIONS(deck)) { std::shared_ptr regionsSection(new Opm::REGIONSSection(deck) ); scanSection(regionsSection, enabledTypes); } if (Section::hasSOLUTION(deck)) { std::shared_ptr solutionSection(new Opm::SOLUTIONSection(deck) ); scanSection(solutionSection, enabledTypes); } } void EclipseState::scanSection(std::shared_ptr section, int enabledTypes) { BoxManager boxManager(m_eclipseGrid->getNX( ) , m_eclipseGrid->getNY() , m_eclipseGrid->getNZ()); for (auto iter = section->begin(); iter != section->end(); ++iter) { DeckKeywordConstPtr deckKeyword = *iter; if (supportsGridProperty(deckKeyword->name(), enabledTypes) ) loadGridPropertyFromDeckKeyword(boxManager.getActiveBox(), deckKeyword, enabledTypes); else { if (deckKeyword->name() == "ADD") handleADDKeyword(deckKeyword , boxManager, enabledTypes); if (deckKeyword->name() == "BOX") handleBOXKeyword(deckKeyword , boxManager); if (deckKeyword->name() == "COPY") handleCOPYKeyword(deckKeyword , boxManager, enabledTypes); if (deckKeyword->name() == "EQUALS") handleEQUALSKeyword(deckKeyword , boxManager, enabledTypes); if (deckKeyword->name() == "ENDBOX") handleENDBOXKeyword(boxManager); if (deckKeyword->name() == "MULTIPLY") handleMULTIPLYKeyword(deckKeyword , boxManager, enabledTypes); boxManager.endKeyword(); } } boxManager.endSection(); } void EclipseState::handleBOXKeyword(DeckKeywordConstPtr deckKeyword , BoxManager& boxManager) { DeckRecordConstPtr record = deckKeyword->getRecord(0); int I1 = record->getItem("I1")->getInt(0) - 1; int I2 = record->getItem("I2")->getInt(0) - 1; int J1 = record->getItem("J1")->getInt(0) - 1; int J2 = record->getItem("J2")->getInt(0) - 1; int K1 = record->getItem("K1")->getInt(0) - 1; int K2 = record->getItem("K2")->getInt(0) - 1; boxManager.setInputBox( I1 , I2 , J1 , J2 , K1 , K2 ); } void EclipseState::handleENDBOXKeyword(BoxManager& boxManager) { boxManager.endInputBox(); } void EclipseState::handleMULTIPLYKeyword(DeckKeywordConstPtr deckKeyword , BoxManager& boxManager, int enabledTypes) { for (auto iter = deckKeyword->begin(); iter != deckKeyword->end(); ++iter) { DeckRecordConstPtr record = *iter; const std::string& field = record->getItem("field")->getString(0); double scaleFactor = record->getItem("factor")->getRawDouble(0); setKeywordBox( record , boxManager ); if (m_intGridProperties->hasKeyword( field )) { if (enabledTypes & IntProperties) { int intFactor = static_cast(scaleFactor); std::shared_ptr > property = m_intGridProperties->getKeyword( field ); property->scale( intFactor , boxManager.getActiveBox() ); } } else if (m_doubleGridProperties->hasKeyword( field )) { if (enabledTypes & DoubleProperties) { std::shared_ptr > property = m_doubleGridProperties->getKeyword( field ); property->scale( scaleFactor , boxManager.getActiveBox() ); } } else if (!m_intGridProperties->supportsKeyword(field) && !m_doubleGridProperties->supportsKeyword(field)) throw std::invalid_argument("Fatal error processing MULTIPLY keyword. Tried to multiply not defined keyword " + field); } } /* The fine print of the manual says the ADD keyword should support some state dependent semantics regarding endpoint scaling arrays in the PROPS section. That is not supported. */ void EclipseState::handleADDKeyword(DeckKeywordConstPtr deckKeyword , BoxManager& boxManager, int enabledTypes) { for (auto iter = deckKeyword->begin(); iter != deckKeyword->end(); ++iter) { DeckRecordConstPtr record = *iter; const std::string& field = record->getItem("field")->getString(0); double shiftValue = record->getItem("shift")->getRawDouble(0); setKeywordBox( record , boxManager ); if (m_intGridProperties->hasKeyword( field )) { if (enabledTypes & IntProperties) { int intShift = static_cast(shiftValue); std::shared_ptr > property = m_intGridProperties->getKeyword( field ); property->add( intShift , boxManager.getActiveBox() ); } } else if (m_doubleGridProperties->hasKeyword( field )) { if (enabledTypes & DoubleProperties) { std::shared_ptr > property = m_doubleGridProperties->getKeyword( field ); double siShiftValue = shiftValue * getSIScaling(property->getKeywordInfo().getDimensionString()); property->add(siShiftValue , boxManager.getActiveBox() ); } } else if (!m_intGridProperties->supportsKeyword(field) && !m_doubleGridProperties->supportsKeyword(field)) throw std::invalid_argument("Fatal error processing ADD keyword. Tried to shift not defined keyword " + field); } } void EclipseState::handleEQUALSKeyword(DeckKeywordConstPtr deckKeyword , BoxManager& boxManager, int enabledTypes) { for (auto iter = deckKeyword->begin(); iter != deckKeyword->end(); ++iter) { DeckRecordConstPtr record = *iter; const std::string& field = record->getItem("field")->getString(0); double value = record->getItem("value")->getRawDouble(0); setKeywordBox( record , boxManager ); if (m_intGridProperties->supportsKeyword( field )) { if (enabledTypes & IntProperties) { int intValue = static_cast(value); std::shared_ptr > property = m_intGridProperties->getKeyword( field ); property->setScalar( intValue , boxManager.getActiveBox() ); } } else if (m_doubleGridProperties->supportsKeyword( field )) { if (enabledTypes & DoubleProperties) { std::shared_ptr > property = m_doubleGridProperties->getKeyword( field ); double siValue = value * getSIScaling(property->getKeywordInfo().getDimensionString()); property->setScalar( siValue , boxManager.getActiveBox() ); } } else throw std::invalid_argument("Fatal error processing EQUALS keyword. Tried to set not defined keyword " + field); } } void EclipseState::handleCOPYKeyword(DeckKeywordConstPtr deckKeyword , BoxManager& boxManager, int enabledTypes) { for (auto iter = deckKeyword->begin(); iter != deckKeyword->end(); ++iter) { DeckRecordConstPtr record = *iter; const std::string& srcField = record->getItem("src")->getString(0); const std::string& targetField = record->getItem("target")->getString(0); setKeywordBox( record , boxManager ); if (m_intGridProperties->hasKeyword( srcField )) { if (enabledTypes & IntProperties) copyIntKeyword( srcField , targetField , boxManager.getActiveBox()); } else if (m_doubleGridProperties->hasKeyword( srcField )) { if (enabledTypes & DoubleProperties) copyDoubleKeyword( srcField , targetField , boxManager.getActiveBox()); } else if (!m_intGridProperties->supportsKeyword(srcField) && !m_doubleGridProperties->supportsKeyword(srcField)) throw std::invalid_argument("Fatal error processing COPY keyword. Tried to copy from not defined keyword " + srcField); } } void EclipseState::copyIntKeyword(const std::string& srcField , const std::string& targetField , std::shared_ptr inputBox) { std::shared_ptr > src = m_intGridProperties->getKeyword( srcField ); std::shared_ptr > target = m_intGridProperties->getKeyword( targetField ); target->copyFrom( *src , inputBox ); } void EclipseState::copyDoubleKeyword(const std::string& srcField , const std::string& targetField , std::shared_ptr inputBox) { std::shared_ptr > src = m_doubleGridProperties->getKeyword( srcField ); std::shared_ptr > target = m_doubleGridProperties->getKeyword( targetField ); target->copyFrom( *src , inputBox ); } void EclipseState::setKeywordBox(DeckRecordConstPtr deckRecord , BoxManager& boxManager) { DeckItemConstPtr I1Item = deckRecord->getItem("I1"); DeckItemConstPtr I2Item = deckRecord->getItem("I2"); DeckItemConstPtr J1Item = deckRecord->getItem("J1"); DeckItemConstPtr J2Item = deckRecord->getItem("J2"); DeckItemConstPtr K1Item = deckRecord->getItem("K1"); DeckItemConstPtr K2Item = deckRecord->getItem("K2"); size_t setCount = 0; if (I1Item->setInDeck()) setCount++; if (I2Item->setInDeck()) setCount++; if (J1Item->setInDeck()) setCount++; if (J2Item->setInDeck()) setCount++; if (K1Item->setInDeck()) setCount++; if (K2Item->setInDeck()) setCount++; if (setCount == 6) { boxManager.setKeywordBox( I1Item->getInt(0) - 1, I2Item->getInt(0) - 1, J1Item->getInt(0) - 1, J2Item->getInt(0) - 1, K1Item->getInt(0) - 1, K2Item->getInt(0) - 1); } else if (setCount != 0) throw std::invalid_argument("When using BOX modifiers on keywords you must specify the BOX completely - or not at all."); } }