/* Copyright 2014 Statoil ASA. This file is part of the Open Porous Media project (OPM). OPM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OPM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OPM. If not, see . */ #ifndef ECLIPSE_GRIDPROPERTIES_HPP_ #define ECLIPSE_GRIDPROPERTIES_HPP_ #include #include #include #include #include #include #include #include /* This class implements a container (std::unordered_map>) of Gridproperties. Usage is as follows: 1. Instantiate the class; passing the number of grid cells and the supported keywords as a list of strings to the constructor. 2. Query the container with the supportsKeyword() and hasKeyword() methods. 3. When you ask the container to get a keyword with the getKeyword() method it will automatically create a new GridProperty object if the container does not have this property. */ namespace Opm { class EclipseGrid; template class GridProperties { public: typedef typename GridProperty::SupportedKeywordInfo SupportedKeywordInfo; GridProperties(std::shared_ptr eclipseGrid, std::vector< SupportedKeywordInfo >&& supportedKeywords) : m_eclipseGrid( eclipseGrid ) { for (auto iter = supportedKeywords.begin(); iter != supportedKeywords.end(); ++iter) m_supportedKeywords[iter->getKeywordName()] = std::move( *iter ); } bool supportsKeyword(const std::string& keyword) const { return m_supportedKeywords.count( keyword ) > 0; } bool hasKeyword(const std::string& keyword) const { return m_properties.count( keyword ) > 0 && !isAutoGenerated_(keyword); } size_t size() const { return m_property_list.size(); } std::shared_ptr > getKeyword(const std::string& keyword) const { if (!hasKeyword(keyword)) addAutoGeneratedKeyword_(keyword); return m_properties.at( keyword ); } std::shared_ptr > getKeyword(size_t index) const { if (index < size()) return m_property_list[index]; else throw std::invalid_argument("Invalid index"); } std::shared_ptr > getInitializedKeyword(const std::string& keyword) const { if (hasKeyword(keyword)) return m_properties.at( keyword ); else { if (supportsKeyword(keyword)) throw std::invalid_argument("Keyword: " + keyword + " is supported - but not initialized."); else throw std::invalid_argument("Keyword: " + keyword + " is not supported."); } } bool addKeyword(const std::string& keywordName) { if (!supportsKeyword( keywordName )) throw std::invalid_argument("The keyword: " + keywordName + " is not supported in this container"); if (hasKeyword(keywordName)) return false; else { // if the property was already added auto generated, we just need to make it // non-auto generated if (m_autoGeneratedProperties_.count(keywordName)) { OpmLog::addMessage(Log::MessageType::Warning, "The keyword "+keywordName+" has been used to calculate the " "defaults of another keyword before the first time it was " "explicitly mentioned in the deck. Maybe you need to change " "the ordering of your keywords (move "+keywordName+" to the " "front?)."); m_autoGeneratedProperties_.erase(m_autoGeneratedProperties_.find(keywordName)); return true; } auto supportedKeyword = m_supportedKeywords.at( keywordName ); int nx = m_eclipseGrid->getNX(); int ny = m_eclipseGrid->getNY(); int nz = m_eclipseGrid->getNZ(); std::shared_ptr > newProperty(new GridProperty(nx , ny , nz , supportedKeyword)); m_properties.insert( std::pair > > ( keywordName , newProperty )); m_property_list.push_back( newProperty ); return true; } } template bool hasKeyword() const { return hasKeyword( Keyword::keywordName ); } template std::shared_ptr > getKeyword() const { return getKeyword( Keyword::keywordName ); } template std::shared_ptr > getInitializedKeyword() const { return getInitializedKeyword( Keyword::keywordName ); } private: bool addAutoGeneratedKeyword_(const std::string& keywordName) const { if (!supportsKeyword( keywordName )) throw std::invalid_argument("The keyword: " + keywordName + " is not supported in this container"); if (m_properties.count( keywordName ) > 0) return false; // property already exists (if it is auto generated or not doesn't matter) else { auto supportedKeyword = m_supportedKeywords.at( keywordName ); int nx = m_eclipseGrid->getNX(); int ny = m_eclipseGrid->getNY(); int nz = m_eclipseGrid->getNZ(); std::shared_ptr > newProperty(new GridProperty(nx , ny , nz , supportedKeyword)); m_autoGeneratedProperties_.insert(keywordName); m_properties.insert( std::pair > > ( keywordName , newProperty )); m_property_list.push_back( newProperty ); return true; } } bool isAutoGenerated_(const std::string& keyword) const { return m_autoGeneratedProperties_.count(keyword); } std::shared_ptr m_eclipseGrid; std::unordered_map m_supportedKeywords; mutable std::map > > m_properties; mutable std::set m_autoGeneratedProperties_; mutable std::vector > > m_property_list; }; } #endif