void checkOptions(const DeckKeyword& keyword, std::multimap<std::string , PartiallySupported<T> >& map, const ParseContext& parseContext, ErrorGuard& errorGuard) { // check for partially supported keywords. typename std::multimap<std::string, PartiallySupported<T> >::iterator it, itlow, itup; itlow = map.lower_bound(keyword.name()); itup = map.upper_bound(keyword.name()); for (it = itlow; it != itup; ++it) { const auto& record = keyword.getRecord(0); if (record.getItem(it->second.item).template get<T>(0) != it->second.item_value) { std::string msg = "For keyword '" + it->first + "' only value " + boost::lexical_cast<std::string>(it->second.item_value) + " in item " + it->second.item + " is supported by flow.\n" + "In file " + keyword.getFileName() + ", line " + std::to_string(keyword.getLineNumber()) + "\n"; parseContext.handleError(ParseContext::SIMULATOR_KEYWORD_ITEM_NOT_SUPPORTED, msg, errorGuard); } } }
void VFPProdTable::check(const DeckKeyword& keyword, const double table_scaling_factor) { //Table number assert(m_table_num > 0); //Misc types assert(m_flo_type >= FLO_OIL && m_flo_type < FLO_INVALID); assert(m_wfr_type >= WFR_WOR && m_wfr_type < WFR_INVALID); assert(m_gfr_type >= GFR_GOR && m_gfr_type < GFR_INVALID); assert(m_alq_type >= ALQ_GRAT && m_alq_type < ALQ_INVALID); //Data axis size assert(m_flo_data.size() > 0); assert(m_thp_data.size() > 0); assert(m_wfr_data.size() > 0); assert(m_gfr_data.size() > 0); assert(m_alq_data.size() > 0); //Data axis sorted? assert(std::is_sorted(m_flo_data.begin(), m_flo_data.end())); assert(std::is_sorted(m_thp_data.begin(), m_thp_data.end())); assert(std::is_sorted(m_wfr_data.begin(), m_wfr_data.end())); assert(std::is_sorted(m_gfr_data.begin(), m_gfr_data.end())); assert(std::is_sorted(m_alq_data.begin(), m_alq_data.end())); //Check data size matches axes assert(m_data.num_dimensions() == 5); assert(m_data.shape()[0] == m_thp_data.size()); assert(m_data.shape()[1] == m_wfr_data.size()); assert(m_data.shape()[2] == m_gfr_data.size()); assert(m_data.shape()[3] == m_alq_data.size()); assert(m_data.shape()[4] == m_flo_data.size()); //Check that all elements have been set typedef array_type::size_type size_type; for (size_type t=0; t<m_data.shape()[0]; ++t) { for (size_type w=0; w<m_data.shape()[1]; ++w) { for (size_type g=0; g<m_data.shape()[2]; ++g) { for (size_type a=0; a<m_data.shape()[3]; ++a) { for (size_type f=0; f<m_data.shape()[4]; ++f) { if (std::isnan(m_data[t][w][g][a][f])) { //TODO: Replace with proper log message std::cerr << "VFPPROD element [" << t << "," << w << "," << g << "," << a << "," << f << "] not set!" << std::endl; throw std::invalid_argument("Missing VFPPROD value"); } } } } } } //Check that bhp(thp) is a monotonic increasing function. //If this is not the case, we might not be able to determine //the thp from the bhp easily std::string points = ""; for (size_type w=0; w<m_data.shape()[1]; ++w) { for (size_type g=0; g<m_data.shape()[2]; ++g) { for (size_type a=0; a<m_data.shape()[3]; ++a) { for (size_type f=0; f<m_data.shape()[4]; ++f) { double bhp_last = m_data[0][w][g][a][f]; for (size_type t=0; t<m_data.shape()[0]; ++t) { if (m_data[t][w][g][a][f] < bhp_last) { points += "At point (FLOW, THP, WFR, GFR, ALQ) = " + std::to_string(f) + " " + std::to_string(t) + " " + std::to_string(w) + " " + std::to_string(g) + " " + std::to_string(a) + " at BHP = " + std::to_string(m_data[t][w][g][a][f] / table_scaling_factor) + "\n"; } bhp_last = m_data[t][w][g][a][f]; } } } } } if (!points.empty()) { OpmLog::warning("VFP table for production wells has BHP versus THP not " + std::string("monotonically increasing.\nThis may cause convergence ") + "issues due to switching between BHP and THP control mode." + std::string("\nIn keyword VFPPROD table number ") + std::to_string(m_table_num) + ", file " + keyword.getFileName() + ", line " + std::to_string(keyword.getLineNumber()) + "\n"); OpmLog::note(points); } }