/* Copyright 2019 Equinor AS. 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 #if HAVE_MPI #include #endif #include "ParallelRestart.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define HANDLE_AS_POD(T) \ std::size_t packSize(const T& data, Dune::MPIHelper::MPICommunicator comm) \ { \ return packSize(data, comm, std::integral_constant()); \ } \ void pack(const T& data, std::vector& buffer, int& position, \ Dune::MPIHelper::MPICommunicator comm) \ { \ pack(data, buffer, position, comm, std::integral_constant()); \ } \ void unpack(T& data, std::vector& buffer, int& position, \ Dune::MPIHelper::MPICommunicator comm) \ { \ unpack(data, buffer, position, comm, std::integral_constant()); \ } namespace { template std::pair, std::vector> splitDynState(const Opm::DynamicState& state) { std::vector unique; for (const auto& w : state.data()) { if (std::find(unique.begin(), unique.end(), w) == unique.end()) unique.push_back(w); } std::vector idxVec; idxVec.reserve(state.data().size()+1); for (const auto& w : state.data()) { auto uIt = std::find(unique.begin(), unique.end(), w); idxVec.push_back(uIt-unique.begin()); } idxVec.push_back(state.initialRange()); return std::make_pair(unique, idxVec); } template void reconstructDynState(const std::vector& unique, const std::vector& idxVec, Opm::DynamicState& result) { std::vector ptrData; for (size_t i = 0; i < idxVec.size()-1; ++i) { ptrData.push_back(unique[idxVec[i]]); } result = Opm::DynamicState(ptrData, idxVec.back()); } } namespace Opm { namespace Mpi { template std::size_t packSize(const T*, std::size_t, Dune::MPIHelper::MPICommunicator, std::integral_constant) { OPM_THROW(std::logic_error, "Packing not (yet) supported for this non-pod type."); } template std::size_t packSize(const T*, std::size_t l, Dune::MPIHelper::MPICommunicator comm, std::integral_constant) { #if HAVE_MPI int size; MPI_Pack_size(1, Dune::MPITraits::getType(), comm, &size); std::size_t totalSize = size; MPI_Pack_size(l, Dune::MPITraits::getType(), comm, &size); return totalSize + size; #else (void) comm; return l-l; #endif } template std::size_t packSize(const T* data, std::size_t l, Dune::MPIHelper::MPICommunicator comm) { return packSize(data, l, comm, typename std::is_pod::type()); } template std::size_t packSize(const std::pair& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.first, comm) + packSize(data.second, comm); } template std::size_t packSize(const std::vector& data, Dune::MPIHelper::MPICommunicator comm) { if (std::is_pod::value) // size written automatically return packSize(data.data(), data.size(), comm); std::size_t size = packSize(data.size(), comm); for (const auto& entry: data) size += packSize(entry, comm); return size; } template std::size_t packSize(const std::vector& data, Dune::MPIHelper::MPICommunicator comm) { bool entry; return packSize(data.size(), comm) + data.size()*packSize(entry,comm); } template typename std::enable_if::value, std::size_t>::type pack_size_tuple_entry(const Tuple&, Dune::MPIHelper::MPICommunicator) { return 0; } template typename std::enable_if::value, std::size_t>::type pack_size_tuple_entry(const Tuple& tuple, Dune::MPIHelper::MPICommunicator comm) { return packSize(std::get(tuple), comm) + pack_size_tuple_entry(tuple, comm); } template std::size_t packSize(const std::tuple& data, Dune::MPIHelper::MPICommunicator comm) { return pack_size_tuple_entry(data, comm); } template std::size_t packSize(const std::unordered_set& data, Dune::MPIHelper::MPICommunicator comm) { std::size_t totalSize = packSize(data.size(), comm); for (const auto& entry : data) { totalSize += packSize(entry, comm); } return totalSize; } template std::size_t packSize(const std::set& data, Dune::MPIHelper::MPICommunicator comm) { std::size_t totalSize = packSize(data.size(), comm); for (const auto& entry : data) { totalSize += packSize(entry, comm); } return totalSize; } template std::size_t packSize(const OrderedMap& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.getIndex(), comm) + packSize(data.getStorage(), comm); } template std::size_t packSize(const DynamicState& data, Dune::MPIHelper::MPICommunicator comm) { auto split = splitDynState(data); return packSize(split.first, comm) + packSize(split.second, comm); } template std::size_t packSize(const DynamicVector& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.data(), comm); } std::size_t packSize(const char* str, Dune::MPIHelper::MPICommunicator comm) { #if HAVE_MPI int size; MPI_Pack_size(1, Dune::MPITraits::getType(), comm, &size); int totalSize = size; MPI_Pack_size(strlen(str)+1, MPI_CHAR, comm, &size); return totalSize + size; #else (void) str; (void) comm; return 0; #endif } std::size_t packSize(const std::string& str, Dune::MPIHelper::MPICommunicator comm) { return packSize(str.c_str(), comm); } template std::size_t packSize(const std::map& data, Dune::MPIHelper::MPICommunicator comm) { std::size_t totalSize = packSize(data.size(), comm); for (const auto& entry: data) { totalSize += packSize(entry, comm); } return totalSize; } template std::size_t packSize(const std::unordered_map& data, Dune::MPIHelper::MPICommunicator comm) { std::size_t totalSize = packSize(data.size(), comm); for (const auto& entry: data) { totalSize += packSize(entry, comm); } return totalSize; } template std::size_t packSize(const std::array& data, Dune::MPIHelper::MPICommunicator comm) { return N*packSize(data[0], comm); } HANDLE_AS_POD(data::Connection) HANDLE_AS_POD(data::CurrentControl) HANDLE_AS_POD(data::Rates) HANDLE_AS_POD(data::Segment) HANDLE_AS_POD(WellBrineProperties) HANDLE_AS_POD(WellFoamProperties) std::size_t packSize(const data::Well& data, Dune::MPIHelper::MPICommunicator comm) { std::size_t size = packSize(data.rates, comm); size += packSize(data.bhp, comm) + packSize(data.thp, comm); size += packSize(data.temperature, comm); size += packSize(data.control, comm); size += packSize(data.connections, comm); size += packSize(data.segments, comm); size += packSize(data.current_control, comm); return size; } std::size_t packSize(const data::CellData& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.dim, comm) + packSize(data.data, comm) + packSize(data.target, comm); } std::size_t packSize(const RestartKey& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.key, comm) + packSize(data.dim, comm) + packSize(data.required, comm); } std::size_t packSize(const data::Solution& data, Dune::MPIHelper::MPICommunicator comm) { // Needs explicit conversion to a supported base type holding the data // to prevent throwing. return packSize(static_cast&>(data), comm); } std::size_t packSize(const data::WellRates& data, Dune::MPIHelper::MPICommunicator comm) { // Needs explicit conversion to a supported base type holding the data // to prevent throwing. return packSize(static_cast&>(data), comm); } std::size_t packSize(const RestartValue& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.solution, comm) + packSize(data.wells, comm) + packSize(data.extra, comm); } std::size_t packSize(const WellType& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.producer(), comm) + packSize(data.preferred_phase(), comm); } template std::size_t packSize(const std::map& data, Dune::MPIHelper::MPICommunicator comm); std::size_t packSize(const VFPInjTable& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.getTableNum(), comm) + packSize(data.getDatumDepth(), comm) + packSize(data.getFloType(), comm) + packSize(data.getFloAxis(), comm) + packSize(data.getTHPAxis(), comm) + packSize(data.getTable(), comm); } std::size_t packSize(const VFPProdTable& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.getTableNum(), comm) + packSize(data.getDatumDepth(), comm) + packSize(data.getFloType(), comm) + packSize(data.getWFRType(), comm) + packSize(data.getGFRType(), comm) + packSize(data.getALQType(), comm) + packSize(data.getFloAxis(), comm) + packSize(data.getTHPAxis(), comm) + packSize(data.getWFRAxis(), comm) + packSize(data.getGFRAxis(), comm) + packSize(data.getALQAxis(), comm) + packSize(data.getTable(), comm); } std::size_t packSize(const WellTracerProperties& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.getConcentrations(), comm); } std::size_t packSize(const UDAValue& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.get_dim(), comm) + packSize(data.is(), comm) + (data.is() ? packSize(data.get(), comm) : packSize(data.get(), comm)); } std::size_t packSize(const Connection& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.dir(), comm) + packSize(data.depth(), comm) + packSize(data.state(), comm) + packSize(data.satTableId(), comm) + packSize(data.complnum(), comm) + packSize(data.CF(), comm) + packSize(data.Kh(), comm) + packSize(data.rw(), comm) + packSize(data.r0(), comm) + packSize(data.skinFactor(), comm) + packSize(data.getI(), comm) + packSize(data.getJ(), comm) + packSize(data.getK(), comm) + packSize(data.kind(), comm) + packSize(data.getSeqIndex(), comm) + packSize(data.getSegDistStart(), comm) + packSize(data.getSegDistEnd(), comm) + packSize(data.getDefaultSatTabId(), comm) + packSize(data.getCompSegSeqIndex(), comm) + packSize(data.segment(), comm) + packSize(data.wellPi(), comm); } std::size_t packSize(const Well::WellInjectionProperties& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.name, comm) + packSize(data.surfaceInjectionRate, comm) + packSize(data.reservoirInjectionRate, comm) + packSize(data.BHPTarget, comm) + packSize(data.THPTarget, comm) + packSize(data.bhp_hist_limit, comm) + packSize(data.thp_hist_limit, comm) + packSize(data.temperature, comm) + packSize(data.BHPH, comm) + packSize(data.THPH, comm) + packSize(data.VFPTableNumber, comm) + packSize(data.predictionMode, comm) + packSize(data.injectionControls, comm) + packSize(data.injectorType, comm) + packSize(data.controlMode, comm); } std::size_t packSize(const WellEconProductionLimits& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.minOilRate(), comm) + packSize(data.minGasRate(), comm) + packSize(data.maxWaterCut(), comm) + packSize(data.maxGasOilRatio(), comm) + packSize(data.maxWaterGasRatio(), comm) + packSize(data.workover(), comm) + packSize(data.endRun(), comm) + packSize(data.followonWell(), comm) + packSize(data.quantityLimit(), comm) + packSize(data.maxSecondaryMaxWaterCut(), comm) + packSize(data.workoverSecondary(), comm) + packSize(data.maxGasLiquidRatio(), comm) + packSize(data.minLiquidRate(), comm) + packSize(data.maxTemperature(), comm) + packSize(data.minReservoirFluidRate(), comm); } std::size_t packSize(const WellConnections& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.ordering(), comm) + packSize(data.getHeadI(), comm) + packSize(data.getHeadJ(), comm) + packSize(data.getConnections(), comm); } std::size_t packSize(const Well::WellProductionProperties& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.name, comm) + packSize(data.OilRate, comm) + packSize(data.WaterRate, comm) + packSize(data.GasRate, comm) + packSize(data.LiquidRate, comm) + packSize(data.ResVRate, comm) + packSize(data.BHPTarget, comm) + packSize(data.THPTarget, comm) + packSize(data.bhp_hist_limit, comm) + packSize(data.thp_hist_limit, comm) + packSize(data.BHPH, comm) + packSize(data.THPH, comm) + packSize(data.VFPTableNumber, comm) + packSize(data.ALQValue, comm) + packSize(data.predictionMode, comm) + packSize(data.controlMode, comm) + packSize(data.whistctl_cmode, comm) + packSize(data.getNumProductionControls(), comm); } std::size_t packSize(const SpiralICD& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.strength(), comm) + packSize(data.length(), comm) + packSize(data.densityCalibration(), comm) + packSize(data.viscosityCalibration(), comm) + packSize(data.criticalValue(), comm) + packSize(data.widthTransitionRegion(), comm) + packSize(data.maxViscosityRatio(), comm) + packSize(data.methodFlowScaling(), comm) + packSize(data.maxAbsoluteRate(), comm) + packSize(data.status(), comm) + packSize(data.scalingFactor(), comm); } std::size_t packSize(const Valve& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.conFlowCoefficient(), comm) + packSize(data.conCrossArea(), comm) + packSize(data.conMaxCrossArea(), comm) + packSize(data.pipeAdditionalLength(), comm) + packSize(data.pipeDiameter(), comm) + packSize(data.pipeRoughness(), comm) + packSize(data.pipeCrossArea(), comm) + packSize(data.status(), comm); } std::size_t packSize(const Segment& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.segmentNumber(), comm) + packSize(data.branchNumber(), comm) + packSize(data.outletSegment(), comm) + packSize(data.inletSegments(), comm) + packSize(data.totalLength(), comm) + packSize(data.depth(), comm) + packSize(data.internalDiameter(), comm) + packSize(data.roughness(), comm) + packSize(data.crossArea(), comm) + packSize(data.volume(), comm) + packSize(data.dataReady(), comm) + packSize(data.segmentType(), comm) + packSize(data.spiralICD(), comm) + packSize(data.getValve(), comm); } template std::size_t packSize(const std::shared_ptr& data, Dune::MPIHelper::MPICommunicator comm) { std::size_t size = packSize(bool(), comm); if (data) size += packSize(*data, comm); return size; } template std::size_t packSize(const std::unique_ptr& data, Dune::MPIHelper::MPICommunicator comm) { std::size_t size = packSize(bool(), comm); if (data) size += packSize(*data, comm); return size; } std::size_t packSize(const Dimension& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.getSIScalingRaw(), comm) + packSize(data.getSIOffset(), comm); } std::size_t packSize(const UnitSystem& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.getName(), comm) + packSize(data.getType(), comm) + packSize(data.getDimensions(), comm) + packSize(data.use_count(), comm); } std::size_t packSize(const WellSegments& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.compPressureDrop(), comm) + packSize(data.segments(), comm); } std::size_t packSize(const Well& data, Dune::MPIHelper::MPICommunicator comm) { std::size_t size = packSize(data.name(), comm) + packSize(data.groupName(), comm) + packSize(data.firstTimeStep(), comm) + packSize(data.seqIndex(), comm) + packSize(data.getHeadI(), comm) + packSize(data.getHeadJ(), comm) + packSize(data.getRefDepth(), comm) + packSize(data.wellType(), comm) + packSize(data.units(), comm) + packSize(data.udqUndefined(), comm) + packSize(data.getStatus(), comm) + packSize(data.getDrainageRadius(), comm) + packSize(data.getAllowCrossFlow(), comm) + packSize(data.getAutomaticShutIn(), comm) + packSize(data.wellGuideRate(), comm) + packSize(data.getEfficiencyFactor(), comm) + packSize(data.getSolventFraction(), comm) + packSize(data.predictionMode(), comm) + packSize(data.getEconLimits(), comm) + packSize(data.getFoamProperties(), comm) + packSize(data.getPolymerProperties(), comm) + packSize(data.getBrineProperties(), comm) + packSize(data.getTracerProperties(), comm) + packSize(data.getConnections(), comm) + packSize(data.getProductionProperties(), comm) + packSize(data.getInjectionProperties(), comm) + packSize(data.hasSegments(), comm); if (data.hasSegments()) size += packSize(data.getSegments(), comm); return size; } template std::size_t packSize(const IOrderSet& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.index(), comm) + packSize(data.data(), comm); } std::size_t packSize(const Group::GroupInjectionProperties& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.phase, comm) + packSize(data.cmode, comm) + packSize(data.surface_max_rate, comm) + packSize(data.resv_max_rate, comm) + packSize(data.target_reinj_fraction, comm) + packSize(data.target_void_fraction, comm) + packSize(data.reinj_group, comm) + packSize(data.voidage_group, comm) + packSize(data.injection_controls, comm); } std::size_t packSize(const Group::GroupProductionProperties& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.cmode, comm) + packSize(data.exceed_action, comm) + packSize(data.oil_target, comm) + packSize(data.water_target, comm) + packSize(data.gas_target, comm) + packSize(data.liquid_target, comm) + packSize(data.guide_rate, comm) + packSize(data.guide_rate_def, comm) + packSize(data.resv_target, comm) + packSize(data.production_controls, comm); } std::size_t packSize(const Group& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.name(), comm) + packSize(data.insert_index(), comm) + packSize(data.initStep(), comm) + packSize(data.udqUndefined(), comm) + packSize(data.units(), comm) + packSize(data.type(), comm) + packSize(data.getGroupEfficiencyFactor(), comm) + packSize(data.getTransferGroupEfficiencyFactor(), comm) + packSize(data.isAvailableForGroupControl(), comm) + packSize(data.getGroupNetVFPTable(), comm) + packSize(data.parent(), comm) + packSize(data.iwells(), comm) + packSize(data.igroups(), comm) + packSize(data.injectionProperties(), comm) + packSize(data.productionProperties(), comm); } std::size_t packSize(const GuideRateConfig& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.getModel(), comm) + packSize(data.getWells(), comm) + packSize(data.getGroups(), comm); } std::size_t packSize(const GConSale::GCONSALEGroup& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.sales_target, comm) + packSize(data.max_sales_rate, comm) + packSize(data.min_sales_rate, comm) + packSize(data.max_proc, comm) + packSize(data.udq_undefined, comm) + packSize(data.unit_system, comm); } std::size_t packSize(const GConSale& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.getGroups(), comm); } std::size_t packSize(const GConSump::GCONSUMPGroup& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.consumption_rate, comm) + packSize(data.import_rate, comm) + packSize(data.network_node, comm) + packSize(data.udq_undefined, comm) + packSize(data.unit_system, comm); } std::size_t packSize(const GConSump& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.getGroups(), comm); } std::size_t packSize(const DeckItem& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.dVal(), comm) + packSize(data.iVal(), comm) + packSize(data.sVal(), comm) + packSize(data.uVal(), comm) + packSize(data.getType(), comm) + packSize(data.name(), comm) + packSize(data.valueStatus(), comm) + packSize(data.rawData(), comm) + packSize(data.activeDimensions(), comm) + packSize(data.defaultDimensions(), comm); } std::size_t packSize(const DeckRecord& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.getItems(), comm); } std::size_t packSize(const Location& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.filename, comm) + packSize(data.lineno, comm); } std::size_t packSize(const DeckKeyword& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.name(), comm) + packSize(data.location(), comm) + packSize(data.records(), comm) + packSize(data.isDataKeyword(), comm) + packSize(data.isSlashTerminated(), comm); } std::size_t packSize(const Deck& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.keywords(), comm) + packSize(data.getDefaultUnitSystem(), comm) + packSize(data.activeUnitSystem(), comm) + packSize(data.getDataFile(), comm) + packSize(data.getInputPath(), comm) + packSize(data.unitSystemAccessCount(), comm); } std::size_t packSize(const Action::ASTNode& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.type, comm) + packSize(data.func_type, comm) + packSize(data.func, comm) + packSize(data.argList(), comm) + packSize(data.getNumber(), comm) + packSize(data.childrens(), comm); } std::size_t packSize(const Action::AST& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.getCondition(), comm); } std::size_t packSize(const Action::Quantity& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.quantity, comm) + packSize(data.args, comm); } std::size_t packSize(const Action::Condition& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.lhs, comm) + packSize(data.rhs, comm) + packSize(data.logic, comm) + packSize(data.cmp, comm) + packSize(data.cmp_string, comm); } std::size_t packSize(const Action::ActionX& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.name(), comm) + packSize(data.max_run(), comm) + packSize(data.min_wait(), comm) + packSize(data.start_time(), comm) + packSize(data.getKeywords(), comm) + packSize(data.getCondition(), comm) + packSize(data.conditions(), comm) + packSize(data.getRunCount(), comm) + packSize(data.getLastRun(), comm); } std::size_t packSize(const Action::Actions& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.getActions(), comm); } std::size_t packSize(const WellPolymerProperties& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.m_polymerConcentration, comm) + packSize(data.m_saltConcentration, comm) + packSize(data.m_plymwinjtable, comm) + packSize(data.m_skprwattable, comm) + packSize(data.m_skprpolytable, comm); } std::size_t packSize(const Well::WellGuideRate& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.available, comm) + packSize(data.guide_rate, comm) + packSize(data.guide_phase, comm) + packSize(data.scale_factor, comm); } std::size_t packSize(const GuideRateConfig::WellTarget& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.guide_rate, comm) + packSize(data.target, comm) + packSize(data.scaling_factor, comm); } std::size_t packSize(const GuideRateConfig::GroupTarget& data, Dune::MPIHelper::MPICommunicator comm) { return packSize(data.guide_rate, comm) + packSize(data.target, comm); } ////// pack routines template void pack(const T*, std::size_t, std::vector&, int&, Dune::MPIHelper::MPICommunicator, std::integral_constant) { OPM_THROW(std::logic_error, "Packing not (yet) supported for this non-pod type."); } template void pack(const T* data, std::size_t l, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm, std::integral_constant) { #if HAVE_MPI MPI_Pack(&l, 1, Dune::MPITraits::getType(), buffer.data(), buffer.size(), &position, comm); MPI_Pack(data, l, Dune::MPITraits::getType(), buffer.data(), buffer.size(), &position, comm); #else (void) data; (void) comm; (void) l; (void) buffer; (void) position; #endif } template void pack(const T* data, std::size_t l, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data, l, buffer, position, comm, typename std::is_pod::type()); } template void pack(const std::pair& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.first, buffer, position, comm); pack(data.second, buffer, position, comm); } template void pack(const std::vector& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { if (std::is_pod::value) { // size written automatically pack(data.data(), data.size(), buffer, position, comm); return; } pack(data.size(), buffer, position, comm); for (const auto& entry: data) pack(entry, buffer, position, comm); } template void pack(const std::set& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.size(), buffer, position, comm); for (const auto& entry : data) { pack(entry, buffer, position, comm); } } template void pack(const std::unordered_set& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.size(), buffer, position, comm); for (const auto& entry : data) { pack(entry, buffer, position, comm); } } template void pack(const std::array& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { for (const T& entry : data) pack(entry, buffer, position, comm); } template void pack(const std::vector& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.size(), buffer, position, comm); for (const auto& entry : data) { bool b = entry; pack(b, buffer, position, comm); } } template typename std::enable_if::value, void>::type pack_tuple_entry(const Tuple&, std::vector&, int&, Dune::MPIHelper::MPICommunicator) { } template typename std::enable_if::value, void>::type pack_tuple_entry(const Tuple& tuple, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(std::get(tuple), buffer, position, comm); pack_tuple_entry(tuple, buffer, position, comm); } template void pack(const std::tuple& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack_tuple_entry(data, buffer, position, comm); } template void pack(const OrderedMap& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.getIndex(), buffer, position, comm); pack(data.getStorage(), buffer, position, comm); } template void pack(const DynamicState& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { auto split = splitDynState(data); pack(split.first, buffer, position, comm); pack(split.second, buffer, position, comm); } template void pack(const DynamicVector& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.data(), buffer, position, comm); } void pack(const char* str, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { #if HAVE_MPI std::size_t length = strlen(str)+1; MPI_Pack(&length, 1, Dune::MPITraits::getType(), buffer.data(), buffer.size(), &position, comm); MPI_Pack(str, strlen(str)+1, MPI_CHAR, buffer.data(), buffer.size(), &position, comm); #else (void) str; (void) comm; (void) buffer; (void) position; #endif } void pack(const std::string& str, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(str.c_str(), buffer, position, comm); } template void pack(const std::map& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.size(), buffer, position, comm); for (const auto& entry: data) { pack(entry, buffer, position, comm); } } template void pack(const std::unordered_map& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.size(), buffer, position, comm); for (const auto& entry: data) { pack(entry, buffer, position, comm); } } template void pack(const std::map& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm); void pack(const data::Well& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.rates, buffer, position, comm); pack(data.bhp, buffer, position, comm); pack(data.thp, buffer, position, comm); pack(data.temperature, buffer, position, comm); pack(data.control, buffer, position, comm); pack(data.connections, buffer, position, comm); pack(data.segments, buffer, position, comm); pack(data.current_control, buffer, position, comm); } void pack(const RestartKey& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.key, buffer, position, comm); pack(data.dim, buffer, position, comm); pack(data.required, buffer, position, comm); } void pack(const data::CellData& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.dim, buffer, position, comm); pack(data.data, buffer, position, comm); pack(data.target, buffer, position, comm); } void pack(const data::Solution& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { // Needs explicit conversion to a supported base type holding the data // to prevent throwing. pack(static_cast&>(data), buffer, position, comm); } void pack(const data::WellRates& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { // Needs explicit conversion to a supported base type holding the data // to prevent throwing. pack(static_cast&>(data), buffer, position, comm); } void pack(const RestartValue& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.solution, buffer, position, comm); pack(data.wells, buffer, position, comm); pack(data.extra, buffer, position, comm); } void pack(const WellType& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.producer(), buffer, position, comm); pack(data.preferred_phase(), buffer, position, comm); } void pack(const VFPInjTable& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.getTableNum(), buffer, position, comm); pack(data.getDatumDepth(), buffer, position, comm); pack(data.getFloType(), buffer, position, comm); pack(data.getFloAxis(), buffer, position, comm); pack(data.getTHPAxis(), buffer, position, comm); pack(data.getTable(), buffer, position, comm); } void pack(const VFPProdTable& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.getTableNum(), buffer, position, comm); pack(data.getDatumDepth(), buffer, position, comm); pack(data.getFloType(), buffer, position, comm); pack(data.getWFRType(), buffer, position, comm); pack(data.getGFRType(), buffer, position, comm); pack(data.getALQType(), buffer, position, comm); pack(data.getFloAxis(), buffer, position, comm); pack(data.getTHPAxis(), buffer, position, comm); pack(data.getWFRAxis(), buffer, position, comm); pack(data.getGFRAxis(), buffer, position, comm); pack(data.getALQAxis(), buffer, position, comm); pack(data.getTable(), buffer, position, comm); } void pack(const WellTracerProperties& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.getConcentrations(), buffer, position, comm); } void pack(const UDAValue& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.get_dim(), buffer, position, comm); pack(data.is(), buffer, position, comm); if (data.is()) pack(data.get(), buffer, position, comm); else pack(data.get(), buffer, position, comm); } void pack(const Connection& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.dir(), buffer, position, comm); pack(data.depth(), buffer, position, comm); pack(data.state(), buffer, position, comm); pack(data.satTableId(), buffer, position, comm); pack(data.complnum(), buffer, position, comm); pack(data.CF(), buffer, position, comm); pack(data.Kh(), buffer, position, comm); pack(data.rw(), buffer, position, comm); pack(data.r0(), buffer, position, comm); pack(data.skinFactor(), buffer, position, comm); pack(data.getI(), buffer, position, comm); pack(data.getJ(), buffer, position, comm); pack(data.getK(), buffer, position, comm); pack(data.kind(), buffer, position, comm); pack(data.getSeqIndex(), buffer, position, comm); pack(data.getSegDistStart(), buffer, position, comm); pack(data.getSegDistEnd(), buffer, position, comm); pack(data.getDefaultSatTabId(), buffer, position, comm); pack(data.getCompSegSeqIndex(), buffer, position, comm); pack(data.segment(), buffer, position, comm); pack(data.wellPi(), buffer, position, comm); } void pack(const Well::WellInjectionProperties& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.name, buffer, position, comm); pack(data.surfaceInjectionRate, buffer, position, comm); pack(data.reservoirInjectionRate, buffer, position, comm); pack(data.BHPTarget, buffer, position, comm); pack(data.THPTarget, buffer, position, comm); pack(data.bhp_hist_limit, buffer, position, comm); pack(data.thp_hist_limit, buffer, position, comm); pack(data.temperature, buffer, position, comm); pack(data.BHPH, buffer, position, comm); pack(data.THPH, buffer, position, comm); pack(data.VFPTableNumber, buffer, position, comm); pack(data.predictionMode, buffer, position, comm); pack(data.injectionControls, buffer, position, comm); pack(data.injectorType, buffer, position, comm); pack(data.controlMode, buffer, position, comm); } void pack(const WellEconProductionLimits& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.minOilRate(), buffer, position, comm); pack(data.minGasRate(), buffer, position, comm); pack(data.maxWaterCut(), buffer, position, comm); pack(data.maxGasOilRatio(), buffer, position, comm); pack(data.maxWaterGasRatio(), buffer, position, comm); pack(data.workover(), buffer, position, comm); pack(data.endRun(), buffer, position, comm); pack(data.followonWell(), buffer, position, comm); pack(data.quantityLimit(), buffer, position, comm); pack(data.maxSecondaryMaxWaterCut(), buffer, position, comm); pack(data.workoverSecondary(), buffer, position, comm); pack(data.maxGasLiquidRatio(), buffer, position, comm); pack(data.minLiquidRate(), buffer, position, comm); pack(data.maxTemperature(), buffer, position, comm); pack(data.minReservoirFluidRate(), buffer, position, comm); } void pack(const WellConnections& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.ordering(), buffer, position, comm); pack(data.getHeadI(), buffer, position, comm); pack(data.getHeadJ(), buffer, position, comm); pack(data.getConnections(), buffer, position, comm); } void pack(const Well::WellProductionProperties& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.name, buffer, position, comm); pack(data.OilRate, buffer, position, comm); pack(data.WaterRate, buffer, position, comm); pack(data.GasRate, buffer, position, comm); pack(data.LiquidRate, buffer, position, comm); pack(data.ResVRate, buffer, position, comm); pack(data.BHPTarget, buffer, position, comm); pack(data.THPTarget, buffer, position, comm); pack(data.bhp_hist_limit, buffer, position, comm); pack(data.thp_hist_limit, buffer, position, comm); pack(data.BHPH, buffer, position, comm); pack(data.THPH, buffer, position, comm); pack(data.VFPTableNumber, buffer, position, comm); pack(data.ALQValue, buffer, position, comm); pack(data.predictionMode, buffer, position, comm); pack(data.controlMode, buffer, position, comm); pack(data.whistctl_cmode, buffer, position, comm); pack(data.getNumProductionControls(), buffer, position, comm); } void pack(const SpiralICD& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.strength(), buffer, position, comm); pack(data.length(), buffer, position, comm); pack(data.densityCalibration(), buffer, position, comm); pack(data.viscosityCalibration(), buffer, position, comm); pack(data.criticalValue(), buffer, position, comm); pack(data.widthTransitionRegion(), buffer, position, comm); pack(data.maxViscosityRatio(), buffer, position, comm); pack(data.methodFlowScaling(), buffer, position, comm); pack(data.maxAbsoluteRate(), buffer, position, comm); pack(data.status(), buffer, position, comm); pack(data.scalingFactor(), buffer, position, comm); } void pack(const Valve& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.conFlowCoefficient(), buffer, position, comm); pack(data.conCrossArea(), buffer, position, comm); pack(data.conMaxCrossArea(), buffer, position, comm); pack(data.pipeAdditionalLength(), buffer, position, comm); pack(data.pipeDiameter(), buffer, position, comm); pack(data.pipeRoughness(), buffer, position, comm); pack(data.pipeCrossArea(), buffer, position, comm); pack(data.status(), buffer, position, comm); } void pack(const Segment& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.segmentNumber(), buffer, position, comm); pack(data.branchNumber(), buffer, position, comm); pack(data.outletSegment(), buffer, position, comm); pack(data.inletSegments(), buffer, position, comm); pack(data.totalLength(), buffer, position, comm); pack(data.depth(), buffer, position, comm); pack(data.internalDiameter(), buffer, position, comm); pack(data.roughness(), buffer, position, comm); pack(data.crossArea(), buffer, position, comm); pack(data.volume(), buffer, position, comm); pack(data.dataReady(), buffer, position, comm); pack(data.segmentType(), buffer, position, comm); pack(data.spiralICD(), buffer, position, comm); pack(data.getValve(), buffer, position, comm); } template void pack(const std::shared_ptr& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data != nullptr, buffer, position, comm); if (data) pack(*data, buffer, position, comm); } template void pack(const std::unique_ptr& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data != nullptr, buffer, position, comm); if (data) pack(*data, buffer, position, comm); } void pack(const Dimension& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.getSIScalingRaw(), buffer, position, comm); pack(data.getSIOffset(), buffer, position, comm); } void pack(const UnitSystem& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.getName(), buffer, position, comm); pack(data.getType(), buffer, position, comm); pack(data.getDimensions(), buffer, position, comm); pack(data.use_count(), buffer, position, comm); } void pack(const WellSegments& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.compPressureDrop(), buffer, position, comm); pack(data.segments(), buffer, position, comm); } void pack(const Well& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.name(), buffer, position, comm); pack(data.groupName(), buffer, position, comm); pack(data.firstTimeStep(), buffer, position, comm); pack(data.seqIndex(), buffer, position, comm); pack(data.getHeadI(), buffer, position, comm); pack(data.getHeadJ(), buffer, position, comm); pack(data.getRefDepth(), buffer, position, comm); pack(data.wellType(), buffer, position, comm); pack(data.units(), buffer, position, comm); pack(data.udqUndefined(), buffer, position, comm); pack(data.getStatus(), buffer, position, comm); pack(data.getDrainageRadius(), buffer, position, comm); pack(data.getAllowCrossFlow(), buffer, position, comm); pack(data.getAutomaticShutIn(), buffer, position, comm); pack(data.wellGuideRate(), buffer, position, comm); pack(data.getEfficiencyFactor(), buffer, position, comm); pack(data.getSolventFraction(), buffer, position, comm); pack(data.predictionMode(), buffer, position, comm); pack(data.getEconLimits(), buffer, position, comm); pack(data.getFoamProperties(), buffer, position, comm); pack(data.getPolymerProperties(), buffer, position, comm); pack(data.getBrineProperties(), buffer, position, comm); pack(data.getTracerProperties(), buffer, position, comm); pack(data.getConnections(), buffer, position, comm); pack(data.getProductionProperties(), buffer, position, comm); pack(data.getInjectionProperties(), buffer, position, comm); pack(data.hasSegments(), buffer, position, comm); if (data.hasSegments()) pack(data.getSegments(), buffer, position, comm); } template void pack(const IOrderSet& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.index(), buffer, position, comm); pack(data.data(), buffer, position, comm); } void pack(const Group::GroupInjectionProperties& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.phase, buffer, position, comm); pack(data.cmode, buffer, position, comm); pack(data.surface_max_rate, buffer, position, comm); pack(data.resv_max_rate, buffer, position, comm); pack(data.target_reinj_fraction, buffer, position, comm); pack(data.target_void_fraction, buffer, position, comm); pack(data.reinj_group, buffer, position, comm); pack(data.voidage_group, buffer, position, comm); pack(data.injection_controls, buffer, position, comm); } void pack(const Group::GroupProductionProperties& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.cmode, buffer, position, comm); pack(data.exceed_action, buffer, position, comm); pack(data.oil_target, buffer, position, comm); pack(data.water_target, buffer, position, comm); pack(data.gas_target, buffer, position, comm); pack(data.liquid_target, buffer, position, comm); pack(data.guide_rate, buffer, position, comm); pack(data.guide_rate_def, buffer, position, comm); pack(data.resv_target, buffer, position, comm); pack(data.production_controls, buffer, position, comm); } void pack(const Group& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.name(), buffer, position, comm); pack(data.insert_index(), buffer, position, comm); pack(data.initStep(), buffer, position, comm); pack(data.udqUndefined(), buffer, position, comm); pack(data.units(), buffer, position, comm); pack(data.type(), buffer, position, comm); pack(data.getGroupEfficiencyFactor(), buffer, position, comm); pack(data.getTransferGroupEfficiencyFactor(), buffer, position, comm); pack(data.isAvailableForGroupControl(), buffer, position, comm); pack(data.getGroupNetVFPTable(), buffer, position, comm); pack(data.parent(), buffer, position, comm); pack(data.iwells(), buffer, position, comm); pack(data.igroups(), buffer, position, comm); pack(data.injectionProperties(), buffer, position, comm); pack(data.productionProperties(), buffer, position, comm); } void pack(const GuideRateConfig& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.getModel(), buffer, position, comm); pack(data.getWells(), buffer, position, comm); pack(data.getGroups(), buffer, position, comm); } void pack(const GConSale::GCONSALEGroup& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.sales_target, buffer, position, comm); pack(data.max_sales_rate, buffer, position, comm); pack(data.min_sales_rate, buffer, position, comm); pack(data.max_proc, buffer, position, comm); pack(data.udq_undefined, buffer, position, comm); pack(data.unit_system, buffer, position, comm); } void pack(const GConSale& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.getGroups(), buffer, position, comm); } void pack(const GConSump::GCONSUMPGroup& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.consumption_rate, buffer, position, comm); pack(data.import_rate, buffer, position, comm); pack(data.network_node, buffer, position, comm); pack(data.udq_undefined, buffer, position, comm); pack(data.unit_system, buffer, position, comm); } void pack(const GConSump& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.getGroups(), buffer, position, comm); } void pack(const DeckItem& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.dVal(), buffer, position, comm); pack(data.iVal(), buffer, position, comm); pack(data.sVal(), buffer, position, comm); pack(data.uVal(), buffer, position, comm); pack(data.getType(), buffer, position, comm); pack(data.name(), buffer, position, comm); pack(data.valueStatus(), buffer, position, comm); pack(data.rawData(), buffer, position, comm); pack(data.activeDimensions(), buffer, position, comm); pack(data.defaultDimensions(), buffer, position, comm); } void pack(const DeckRecord& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.getItems(), buffer, position, comm); } void pack(const Location& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.filename, buffer, position, comm); pack(data.lineno, buffer, position, comm); } void pack(const DeckKeyword& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.name(), buffer, position, comm); pack(data.location(), buffer, position, comm); pack(data.records(), buffer, position, comm); pack(data.isDataKeyword(), buffer, position, comm); pack(data.isSlashTerminated(), buffer, position, comm); } void pack(const Deck& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.keywords(), buffer, position, comm); pack(data.getDefaultUnitSystem(), buffer, position, comm); pack(data.activeUnitSystem(), buffer, position, comm); pack(data.getDataFile(), buffer, position, comm); pack(data.getInputPath(), buffer, position, comm); pack(data.unitSystemAccessCount(), buffer, position, comm); } void pack(const Action::ASTNode& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.type, buffer, position, comm); pack(data.func_type, buffer, position, comm); pack(data.func, buffer, position, comm); pack(data.argList(), buffer, position, comm); pack(data.getNumber(), buffer, position, comm); pack(data.childrens(), buffer, position, comm); } void pack(const Action::AST& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.getCondition(), buffer, position, comm); } void pack(const Action::Quantity& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.quantity, buffer, position, comm); pack(data.args, buffer, position, comm); } void pack(const Action::Condition& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.lhs, buffer, position, comm); pack(data.rhs, buffer, position, comm); pack(data.logic, buffer, position, comm); pack(data.cmp, buffer, position, comm); pack(data.cmp_string, buffer, position, comm); } void pack(const Action::ActionX& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.name(), buffer, position, comm); pack(data.max_run(), buffer, position, comm); pack(data.min_wait(), buffer, position, comm); pack(data.start_time(), buffer, position, comm); pack(data.getKeywords(), buffer, position, comm); pack(data.getCondition(), buffer, position, comm); pack(data.conditions(), buffer, position, comm); pack(data.getRunCount(), buffer, position, comm); pack(data.getLastRun(), buffer, position, comm); } void pack(const Action::Actions& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.getActions(), buffer, position, comm); } void pack(const WellPolymerProperties& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.m_polymerConcentration, buffer, position, comm); pack(data.m_saltConcentration, buffer, position, comm); pack(data.m_plymwinjtable, buffer, position, comm); pack(data.m_skprwattable, buffer, position, comm); pack(data.m_skprpolytable, buffer, position, comm); } void pack(const Well::WellGuideRate& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.available, buffer, position, comm); pack(data.guide_rate, buffer, position, comm); pack(data.guide_phase, buffer, position, comm); pack(data.scale_factor, buffer, position, comm); } void pack(const GuideRateConfig::WellTarget& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.guide_rate, buffer, position, comm); pack(data.target, buffer, position, comm); pack(data.scaling_factor, buffer, position, comm); } void pack(const GuideRateConfig::GroupTarget& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { pack(data.guide_rate, buffer, position, comm); pack(data.target, buffer, position, comm); } /// unpack routines template void unpack(T*, const std::size_t&, std::vector&, int&, Dune::MPIHelper::MPICommunicator, std::integral_constant) { OPM_THROW(std::logic_error, "Packing not (yet) supported for this non-pod type."); } template void unpack(T* data, const std::size_t& l, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm, std::integral_constant) { #if HAVE_MPI MPI_Unpack(buffer.data(), buffer.size(), &position, data, l, Dune::MPITraits::getType(), comm); #else (void) data; (void) comm; (void) l; (void) buffer; (void) position; #endif } template void unpack(T* data, const std::size_t& l, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { unpack(data, l, buffer, position, comm, typename std::is_pod::type()); } template void unpack(std::pair& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { unpack(data.first, buffer, position, comm); unpack(data.second, buffer, position, comm); } template void unpack(std::vector& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { std::size_t length = 0; unpack(length, buffer, position, comm); data.resize(length); if (std::is_pod::value) { unpack(data.data(), data.size(), buffer, position, comm); return; } for (auto& entry: data) unpack(entry, buffer, position, comm); } template void unpack(std::vector& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { size_t size; unpack(size, buffer, position, comm); data.clear(); data.reserve(size); for (size_t i = 0; i < size; ++i) { bool entry; unpack(entry, buffer, position, comm); data.push_back(entry); } } template typename std::enable_if::value, void>::type unpack_tuple_entry(Tuple&, std::vector&, int&, Dune::MPIHelper::MPICommunicator) { } template typename std::enable_if::value, void>::type unpack_tuple_entry(Tuple& tuple, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { unpack(std::get(tuple), buffer, position, comm); unpack_tuple_entry(tuple, buffer, position, comm); } template void unpack(std::tuple& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { unpack_tuple_entry(data, buffer, position, comm); } template void unpack(std::set& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { std::size_t size = 0; unpack(size, buffer, position, comm); for (;size>0; size--) { K entry; unpack(entry, buffer, position, comm); data.insert(entry); } } template void unpack(std::unordered_set& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { std::size_t size=0; unpack(size, buffer, position, comm); for (;size>0; size--) { T entry; unpack(entry, buffer, position, comm); data.insert(entry); } } template void unpack(std::array& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { for (T& entry : data) unpack(entry, buffer, position, comm); } template void unpack(OrderedMap& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { typename OrderedMap::index_type index; typename OrderedMap::storage_type storage; unpack(index, buffer, position, comm); unpack(storage, buffer, position, comm); data = OrderedMap(index, storage); } template void unpack(DynamicState& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { std::vector unique; std::vector indices; Opm::Mpi::unpack(unique, buffer, position, comm); Opm::Mpi::unpack(indices, buffer, position, comm); reconstructDynState(unique, indices, data); } template void unpack(DynamicVector& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { std::vector ddata; unpack(ddata, buffer, position, comm); data = DynamicVector(ddata); } void unpack(char* str, std::size_t length, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { #if HAVE_MPI MPI_Unpack(buffer.data(), buffer.size(), &position, const_cast(str), length, MPI_CHAR, comm); #else (void) str; (void) comm; (void) length; (void) buffer; (void) position; #endif } void unpack(std::string& str, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { std::size_t length=0; unpack(length, buffer, position, comm); std::vector cStr(length, '\0'); unpack(cStr.data(), length, buffer, position, comm); str.clear(); str.append(cStr.data()); } template void unpack(std::map& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { std::size_t size=0; unpack(size, buffer, position, comm); for (;size>0; size--) { std::pair entry; unpack(entry, buffer, position, comm); data.insert(entry); } } template void unpack(std::unordered_map& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { std::size_t size=0; unpack(size, buffer, position, comm); for (;size>0; size--) { std::pair entry; unpack(entry, buffer, position, comm); data.insert(entry); } } void unpack(data::Well& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { unpack(data.rates, buffer, position, comm); unpack(data.bhp, buffer, position, comm); unpack(data.thp, buffer, position, comm); unpack(data.temperature, buffer, position, comm); unpack(data.control, buffer, position, comm); unpack(data.connections, buffer, position, comm); unpack(data.segments, buffer, position, comm); unpack(data.current_control, buffer, position, comm); } void unpack(RestartKey& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { unpack(data.key, buffer, position, comm); unpack(data.dim, buffer, position, comm); unpack(data.required, buffer, position, comm); } void unpack(data::CellData& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { unpack(data.dim, buffer, position, comm); unpack(data.data, buffer, position, comm); unpack(data.target, buffer, position, comm); } void unpack(data::Solution& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { // Needs explicit conversion to a supported base type holding the data // to prevent throwing. unpack(static_cast&>(data), buffer, position, comm); } void unpack(data::WellRates& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { // Needs explicit conversion to a supported base type holding the data // to prevent throwing. unpack(static_cast&>(data), buffer, position, comm); } void unpack(RestartValue& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { unpack(data.solution, buffer, position, comm); unpack(data.wells, buffer, position, comm); unpack(data.extra, buffer, position, comm); } void unpack(WellType& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { Phase preferred_phase; bool producer; unpack(producer, buffer, position, comm); unpack(preferred_phase, buffer, position, comm); data = WellType( producer, preferred_phase ); } void unpack(VFPInjTable& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { int tableNum; double datumDepth; VFPInjTable::FLO_TYPE floType; std::vector floAxis, thpAxis; VFPInjTable::array_type table; unpack(tableNum, buffer, position, comm); unpack(datumDepth, buffer, position, comm); unpack(floType, buffer, position, comm); unpack(floAxis, buffer, position, comm); unpack(thpAxis, buffer, position, comm); unpack(table, buffer, position, comm); data = VFPInjTable(tableNum, datumDepth, floType, floAxis, thpAxis, table); } void unpack(VFPProdTable& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { int tableNum; double datumDepth; VFPProdTable::FLO_TYPE floType; VFPProdTable::WFR_TYPE wfrType; VFPProdTable::GFR_TYPE gfrType; VFPProdTable::ALQ_TYPE alqType; std::vector floAxis, thpAxis, wfrAxis, gfrAxis, alqAxis; VFPProdTable::array_type table; unpack(tableNum, buffer, position, comm); unpack(datumDepth, buffer, position, comm); unpack(floType, buffer, position, comm); unpack(wfrType, buffer, position, comm); unpack(gfrType, buffer, position, comm); unpack(alqType, buffer, position, comm); unpack(floAxis, buffer, position, comm); unpack(thpAxis, buffer, position, comm); unpack(wfrAxis, buffer, position, comm); unpack(gfrAxis, buffer, position, comm); unpack(alqAxis, buffer, position, comm); unpack(table, buffer, position, comm); data = VFPProdTable(tableNum, datumDepth, floType, wfrType, gfrType, alqType, floAxis, thpAxis, wfrAxis, gfrAxis, alqAxis, table); } void unpack(WellTracerProperties& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { WellTracerProperties::ConcentrationMap ddata; unpack(ddata, buffer, position, comm); data = WellTracerProperties(ddata); } void unpack(UDAValue& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { bool isDouble; Dimension dim; unpack(dim, buffer, position, comm); unpack(isDouble, buffer, position, comm); if (isDouble) { double val; unpack(val, buffer, position, comm); data = UDAValue(val, dim); } else { std::string val; unpack(val, buffer, position, comm); data = UDAValue(val, dim); } } void unpack(Connection& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { Connection::Direction dir; double depth; Connection::State state; int satTableId, complnum; double CF, Kh, rw, r0, skinFactor; int I, J, K; size_t seqIndex; double segDistStart, segDistEnd; bool defaultSatTabId; size_t compSegSeqIndex; int segment; double wellPi; Connection::CTFKind kind; unpack(dir, buffer, position, comm); unpack(depth, buffer, position, comm); unpack(state, buffer, position, comm); unpack(satTableId, buffer, position, comm); unpack(complnum, buffer, position, comm); unpack(CF, buffer, position, comm); unpack(Kh, buffer, position, comm); unpack(rw, buffer, position, comm); unpack(r0, buffer, position, comm); unpack(skinFactor, buffer, position, comm); unpack(I, buffer, position, comm); unpack(J, buffer, position, comm); unpack(K, buffer, position, comm); unpack(kind, buffer, position, comm); unpack(seqIndex, buffer, position, comm); unpack(segDistStart, buffer, position, comm); unpack(segDistEnd, buffer, position, comm); unpack(defaultSatTabId, buffer, position, comm); unpack(compSegSeqIndex, buffer, position, comm); unpack(segment, buffer, position, comm); unpack(wellPi, buffer, position, comm); data = Connection(dir, depth, state, satTableId, complnum, CF, Kh, rw, r0, skinFactor, {I,J,K}, kind, seqIndex, segDistStart, segDistEnd, defaultSatTabId, compSegSeqIndex, segment, wellPi); } void unpack(Well::WellInjectionProperties& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { unpack(data.name, buffer, position, comm); unpack(data.surfaceInjectionRate, buffer, position, comm); unpack(data.reservoirInjectionRate, buffer, position, comm); unpack(data.BHPTarget, buffer, position, comm); unpack(data.THPTarget, buffer, position, comm); unpack(data.bhp_hist_limit, buffer, position, comm); unpack(data.thp_hist_limit, buffer, position, comm); unpack(data.temperature, buffer, position, comm); unpack(data.BHPH, buffer, position, comm); unpack(data.THPH, buffer, position, comm); unpack(data.VFPTableNumber, buffer, position, comm); unpack(data.predictionMode, buffer, position, comm); unpack(data.injectionControls, buffer, position, comm); unpack(data.injectorType, buffer, position, comm); unpack(data.controlMode, buffer, position, comm); } void unpack(WellEconProductionLimits& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { double minOilRate, minGasRate, maxWaterCut, maxGasOilRatio, maxWaterGasRatio; WellEconProductionLimits::EconWorkover workover, workoverSecondary; bool endRun; std::string followonWell; WellEconProductionLimits::QuantityLimit quantityLimit; double secondaryMaxWaterCut, maxGasLiquidRatio, minLiquidRate, maxTemperature, minReservoirFluidRate; unpack(minOilRate, buffer, position, comm); unpack(minGasRate, buffer, position, comm); unpack(maxWaterCut, buffer, position, comm); unpack(maxGasOilRatio, buffer, position, comm); unpack(maxWaterGasRatio, buffer, position, comm); unpack(workover, buffer, position, comm); unpack(endRun, buffer, position, comm); unpack(followonWell, buffer, position, comm); unpack(quantityLimit, buffer, position, comm); unpack(secondaryMaxWaterCut, buffer, position, comm); unpack(workoverSecondary, buffer, position, comm); unpack(maxGasLiquidRatio, buffer, position, comm); unpack(minLiquidRate, buffer, position, comm); unpack(maxTemperature, buffer, position, comm); unpack(minReservoirFluidRate, buffer, position, comm); data = WellEconProductionLimits(minOilRate, minGasRate, maxWaterCut, maxGasOilRatio, maxWaterGasRatio, workover, endRun, followonWell, quantityLimit, secondaryMaxWaterCut, workoverSecondary, maxGasLiquidRatio, minLiquidRate, maxTemperature, minReservoirFluidRate); } void unpack(WellConnections& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { int headI, headJ; Connection::Order ordering; std::vector connections; unpack(ordering, buffer, position, comm), unpack(headI, buffer, position, comm), unpack(headJ, buffer, position, comm), unpack(connections, buffer, position, comm), data = WellConnections(ordering, headI, headJ, connections); } void unpack(Well::WellProductionProperties& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { std::string name; UDAValue OilRate, WaterRate, GasRate, LiquidRate, ResVRate; UDAValue BHPTarget, THPTarget; double bhp_hist_limit, thp_hist_limit; double BHPH, THPH; int VFPTableNumber; double ALQValue; bool predictionMode; Well::ProducerCMode controlMode, whistctl_cmode; int prodCtrls; unpack(name, buffer, position, comm); unpack(OilRate, buffer, position, comm); unpack(WaterRate, buffer, position, comm); unpack(GasRate, buffer, position, comm); unpack(LiquidRate, buffer, position, comm); unpack(ResVRate, buffer, position, comm); unpack(BHPTarget, buffer, position, comm); unpack(THPTarget, buffer, position, comm); unpack(bhp_hist_limit, buffer, position, comm); unpack(thp_hist_limit, buffer, position, comm); unpack(BHPH, buffer, position, comm); unpack(THPH, buffer, position, comm); unpack(VFPTableNumber, buffer, position, comm); unpack(ALQValue, buffer, position, comm); unpack(predictionMode, buffer, position, comm); unpack(controlMode, buffer, position, comm); unpack(whistctl_cmode, buffer, position, comm); unpack(prodCtrls, buffer, position, comm); data = Well::WellProductionProperties(name, OilRate, WaterRate, GasRate, LiquidRate, ResVRate, BHPTarget, THPTarget, bhp_hist_limit, thp_hist_limit, BHPH, THPH, VFPTableNumber, ALQValue, predictionMode, controlMode, whistctl_cmode, prodCtrls); } void unpack(SpiralICD& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { double strength, length, densityCalibration, viscosityCalibration, criticalValue, widthTransitionRegion, maxViscosityRatio; int methodFlowScaling; double maxAbsoluteRate; ICDStatus status; double scalingFactor; unpack(strength, buffer, position, comm); unpack(length, buffer, position, comm); unpack(densityCalibration, buffer, position, comm); unpack(viscosityCalibration, buffer, position, comm); unpack(criticalValue, buffer, position, comm); unpack(widthTransitionRegion, buffer, position, comm); unpack(maxViscosityRatio, buffer, position, comm); unpack(methodFlowScaling, buffer, position, comm); unpack(maxAbsoluteRate, buffer, position, comm); unpack(status, buffer, position, comm); unpack(scalingFactor, buffer, position, comm); data = SpiralICD(strength, length, densityCalibration, viscosityCalibration, criticalValue, widthTransitionRegion, maxViscosityRatio, methodFlowScaling, maxAbsoluteRate, status, scalingFactor); } void unpack(Valve& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { double conFlowCoefficient; double conCrossArea; double conMaxCrossArea; double pipeAdditionalLength; double pipeDiameter; double pipeRoughness; double pipeCrossArea; ICDStatus status; unpack(conFlowCoefficient, buffer, position, comm); unpack(conCrossArea, buffer, position, comm); unpack(conMaxCrossArea, buffer, position, comm); unpack(pipeAdditionalLength, buffer, position, comm); unpack(pipeDiameter, buffer, position, comm); unpack(pipeRoughness, buffer, position, comm); unpack(pipeCrossArea, buffer, position, comm); unpack(status, buffer, position, comm); data = Valve(conFlowCoefficient, conCrossArea, conMaxCrossArea, pipeAdditionalLength, pipeDiameter, pipeRoughness, pipeCrossArea, status); } void unpack(Segment& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { int segmentNumber, branchNumber, outletSegment; std::vector inletSegments; double totalLength, depth, internalDiameter, roughness, crossArea, volume; bool dataReady; Segment::SegmentType segmentType; std::shared_ptr spiralICD; std::shared_ptr valve; unpack(segmentNumber, buffer, position, comm); unpack(branchNumber, buffer, position, comm); unpack(outletSegment, buffer, position, comm); unpack(inletSegments, buffer, position, comm); unpack(totalLength, buffer, position, comm); unpack(depth, buffer, position, comm); unpack(internalDiameter, buffer, position, comm); unpack(roughness, buffer, position, comm); unpack(crossArea, buffer, position, comm); unpack(volume, buffer, position, comm); unpack(dataReady, buffer, position, comm); unpack(segmentType, buffer, position, comm); unpack(spiralICD, buffer, position, comm); unpack(valve, buffer, position, comm); data = Segment(segmentNumber, branchNumber, outletSegment, inletSegments, totalLength, depth, internalDiameter, roughness, crossArea, volume, dataReady, segmentType, spiralICD, valve); } template void unpack(std::shared_ptr& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { bool hasVal; unpack(hasVal, buffer, position, comm); if (hasVal) { data = std::make_shared(); unpack(*data, buffer, position, comm); } } template void unpack(std::unique_ptr& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { bool hasVal; unpack(hasVal, buffer, position, comm); if (hasVal) { data.reset(new T); unpack(*data, buffer, position, comm); } } void unpack(Dimension& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { double siScaling, siOffset; unpack(siScaling, buffer, position, comm); unpack(siOffset, buffer, position, comm); data = Dimension(siScaling, siOffset); } void unpack(UnitSystem& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { std::string name; UnitSystem::UnitType type; std::map dimensions; size_t use_count; unpack(name, buffer, position, comm); unpack(type, buffer, position, comm); unpack(dimensions, buffer, position, comm); unpack(use_count, buffer, position, comm); data = UnitSystem(name, type, dimensions, use_count); } void unpack(WellSegments& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { WellSegments::CompPressureDrop compPressureDrop; std::vector segments; unpack(compPressureDrop, buffer, position, comm); unpack(segments, buffer, position, comm); data = WellSegments(compPressureDrop, segments); } void unpack(Well& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { std::string name, groupName; std::size_t firstTimeStep, seqIndex; int headI, headJ; double ref_depth; WellType wtype; UnitSystem units; double udq_undefined; Well::Status status; double drainageRadius; bool allowCrossFlow, automaticShutIn; Well::WellGuideRate guideRate; double efficiencyFactor; double solventFraction; bool prediction_mode; auto econLimits = std::make_shared(); auto foamProperties = std::make_shared(); auto polymerProperties = std::make_shared(); auto brineProperties = std::make_shared(); auto tracerProperties = std::make_shared(); auto connection = std::make_shared(); auto production = std::make_shared(); auto injection = std::make_shared(); std::shared_ptr segments; unpack(name, buffer, position, comm); unpack(groupName, buffer, position, comm); unpack(firstTimeStep, buffer, position, comm); unpack(seqIndex, buffer, position, comm); unpack(headI, buffer, position, comm); unpack(headJ, buffer, position, comm); unpack(ref_depth, buffer, position, comm); unpack(wtype, buffer, position, comm); unpack(units, buffer, position, comm); unpack(udq_undefined, buffer, position, comm); unpack(status, buffer, position, comm); unpack(drainageRadius, buffer, position, comm); unpack(allowCrossFlow, buffer, position, comm); unpack(automaticShutIn, buffer, position, comm); unpack(guideRate, buffer, position, comm); unpack(efficiencyFactor, buffer, position, comm); unpack(solventFraction, buffer, position, comm); unpack(prediction_mode, buffer, position, comm); unpack(*econLimits, buffer, position, comm); unpack(*foamProperties, buffer, position, comm); unpack(*polymerProperties, buffer, position, comm); unpack(*brineProperties, buffer, position, comm); unpack(*tracerProperties, buffer, position, comm); unpack(*connection, buffer, position, comm); unpack(*production, buffer, position, comm); unpack(*injection, buffer, position, comm); bool hasSegments; unpack(hasSegments, buffer, position, comm); if (hasSegments) { segments = std::make_shared(); unpack(*segments, buffer, position, comm); } data = Well(name, groupName, firstTimeStep, seqIndex, headI, headJ, ref_depth, wtype, units, udq_undefined, status, drainageRadius, allowCrossFlow, automaticShutIn, guideRate, efficiencyFactor, solventFraction, prediction_mode, econLimits, foamProperties, polymerProperties, brineProperties, tracerProperties, connection, production, injection, segments); } template void unpack(IOrderSet& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { typename IOrderSet::index_type index; typename IOrderSet::storage_type storage; unpack(index, buffer, position, comm); unpack(storage, buffer, position, comm); data = IOrderSet(index, storage); } template void unpack(std::map& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm); void unpack(Group::GroupInjectionProperties& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { unpack(data.phase, buffer, position, comm); unpack(data.cmode, buffer, position, comm); unpack(data.surface_max_rate, buffer, position, comm); unpack(data.resv_max_rate, buffer, position, comm); unpack(data.target_reinj_fraction, buffer, position, comm); unpack(data.target_void_fraction, buffer, position, comm); unpack(data.reinj_group, buffer, position, comm); unpack(data.voidage_group, buffer, position, comm); unpack(data.injection_controls, buffer, position, comm); } void unpack(Group::GroupProductionProperties& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { unpack(data.cmode, buffer, position, comm); unpack(data.exceed_action, buffer, position, comm); unpack(data.oil_target, buffer, position, comm); unpack(data.water_target, buffer, position, comm); unpack(data.gas_target, buffer, position, comm); unpack(data.liquid_target, buffer, position, comm); unpack(data.guide_rate, buffer, position, comm); unpack(data.guide_rate_def, buffer, position, comm); unpack(data.resv_target, buffer, position, comm); unpack(data.production_controls, buffer, position, comm); } void unpack(Group& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { std::string name; std::size_t insert_index, initStep; double udqUndefined; UnitSystem units; Group::GroupType type; double groupEfficiencyFactor; bool transferGroupEfficiencyFactor; bool availableForGroupControl; int groupNetVFPTable; std::string parent; IOrderSet wells, groups; std::map injection; Group::GroupProductionProperties production; unpack(name, buffer, position, comm); unpack(insert_index, buffer, position, comm); unpack(initStep, buffer, position, comm); unpack(udqUndefined, buffer, position, comm); unpack(units, buffer, position, comm); unpack(type, buffer, position, comm); unpack(groupEfficiencyFactor, buffer, position, comm); unpack(transferGroupEfficiencyFactor, buffer, position, comm); unpack(availableForGroupControl, buffer, position, comm); unpack(groupNetVFPTable, buffer, position, comm); unpack(parent, buffer, position, comm); unpack(wells, buffer, position, comm); unpack(groups, buffer, position, comm); unpack(injection, buffer, position, comm); unpack(production, buffer, position, comm); data = Group(name, insert_index, initStep, udqUndefined, units, type, groupEfficiencyFactor, transferGroupEfficiencyFactor, availableForGroupControl, groupNetVFPTable, parent, wells, groups, injection, production); } void unpack(GuideRateConfig& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { std::shared_ptr model; std::unordered_map wells; std::unordered_map groups; unpack(model, buffer, position, comm); unpack(wells, buffer, position, comm); unpack(groups, buffer, position, comm); data = GuideRateConfig(model, wells, groups); } void unpack(GConSale::GCONSALEGroup& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { unpack(data.sales_target, buffer, position, comm); unpack(data.max_sales_rate, buffer, position, comm); unpack(data.min_sales_rate, buffer, position, comm); unpack(data.max_proc, buffer, position, comm); unpack(data.udq_undefined, buffer, position, comm); unpack(data.unit_system, buffer, position, comm); } void unpack(GConSale& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { std::map groups; unpack(groups, buffer, position, comm); data = GConSale(groups); } void unpack(GConSump::GCONSUMPGroup& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { unpack(data.consumption_rate, buffer, position, comm); unpack(data.import_rate, buffer, position, comm); unpack(data.network_node, buffer, position, comm); unpack(data.udq_undefined, buffer, position, comm); unpack(data.unit_system, buffer, position, comm); } void unpack(GConSump& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { std::map groups; unpack(groups, buffer, position, comm); data = GConSump(groups); } void unpack(DeckItem& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { std::vector dVal; std::vector iVal; std::vector sVal; std::vector uVal; type_tag type; std::string name; std::vector valueStatus; bool rawData; std::vector activeDimensions, defaultDimensions; unpack(dVal, buffer, position, comm); unpack(iVal, buffer, position, comm); unpack(sVal, buffer, position, comm); unpack(uVal, buffer, position, comm); unpack(type, buffer, position, comm); unpack(name, buffer, position, comm); unpack(valueStatus, buffer, position, comm); unpack(rawData, buffer, position, comm); unpack(activeDimensions, buffer, position, comm); unpack(defaultDimensions, buffer, position, comm); data = DeckItem(dVal, iVal, sVal, uVal, type, name, valueStatus, rawData, activeDimensions, defaultDimensions); } void unpack(DeckRecord& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { std::vector items; unpack(items, buffer, position, comm); data = DeckRecord(std::move(items)); } void unpack(Location& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { data.filename.clear(); unpack(data.filename, buffer, position, comm); unpack(data.lineno, buffer, position, comm); } void unpack(DeckKeyword& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { std::string name; Location location; std::vector records; bool isDataKeyword, isSlashTerminated; unpack(name, buffer, position, comm); unpack(location, buffer, position, comm); unpack(records, buffer, position, comm); unpack(isDataKeyword, buffer, position, comm); unpack(isSlashTerminated, buffer, position, comm); data = DeckKeyword(name, location, records, isDataKeyword, isSlashTerminated); } void unpack(Deck& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { std::vector keywords; UnitSystem defaultUnitSystem; std::unique_ptr activeUnitSystem; std::string dataFile, inputPath; size_t accessCount; unpack(keywords, buffer, position, comm); unpack(defaultUnitSystem, buffer, position, comm); unpack(activeUnitSystem, buffer, position, comm); unpack(dataFile, buffer, position, comm); unpack(inputPath, buffer, position, comm); unpack(accessCount, buffer, position, comm); data = Deck(keywords, defaultUnitSystem, activeUnitSystem.get(), dataFile, inputPath, accessCount); } void unpack(Action::ASTNode& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { TokenType token; FuncType func_type; std::string func; std::vector argList; double number; std::vector children; unpack(token, buffer, position, comm); unpack(func_type, buffer, position, comm); unpack(func, buffer, position, comm); unpack(argList, buffer, position, comm); unpack(number, buffer, position, comm); unpack(children, buffer, position, comm); data = Action::ASTNode(token, func_type, func, argList, number, children); } void unpack(Action::AST& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { std::shared_ptr condition; unpack(condition, buffer, position, comm); data = Action::AST(condition); } void unpack(Action::Quantity& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { unpack(data.quantity, buffer, position, comm); unpack(data.args, buffer, position, comm); } void unpack(Action::Condition& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { unpack(data.lhs, buffer, position, comm); unpack(data.rhs, buffer, position, comm); unpack(data.logic, buffer, position, comm); unpack(data.cmp, buffer, position, comm); unpack(data.cmp_string, buffer, position, comm); } void unpack(Action::ActionX& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { std::string name; size_t max_run; double min_wait; std::time_t start_time; std::vector keywords; Action::AST condition; std::vector conditions; size_t run_count; std::time_t last_run; unpack(name, buffer, position, comm); unpack(max_run, buffer, position, comm); unpack(min_wait, buffer, position, comm); unpack(start_time, buffer, position, comm); unpack(keywords, buffer, position, comm); unpack(condition, buffer, position, comm); unpack(conditions, buffer, position, comm); unpack(run_count, buffer, position, comm); unpack(last_run, buffer, position, comm); data = Action::ActionX(name, max_run, min_wait, start_time, keywords, condition, conditions, run_count, last_run); } void unpack(Action::Actions& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { std::vector actions; unpack(actions, buffer, position, comm); data = Action::Actions(actions); } void unpack(WellPolymerProperties& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { unpack(data.m_polymerConcentration, buffer, position, comm); unpack(data.m_saltConcentration, buffer, position, comm); unpack(data.m_plymwinjtable, buffer, position, comm); unpack(data.m_skprwattable, buffer, position, comm); unpack(data.m_skprpolytable, buffer, position, comm); } void unpack(Well::WellGuideRate& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { unpack(data.available, buffer, position, comm); unpack(data.guide_rate, buffer, position, comm); unpack(data.guide_phase, buffer, position, comm); unpack(data.scale_factor, buffer, position, comm); } void unpack(GuideRateConfig::WellTarget& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { unpack(data.guide_rate, buffer, position, comm); unpack(data.target, buffer, position, comm); unpack(data.scaling_factor, buffer, position, comm); } void unpack(GuideRateConfig::GroupTarget& data, std::vector& buffer, int& position, Dune::MPIHelper::MPICommunicator comm) { unpack(data.guide_rate, buffer, position, comm); unpack(data.target, buffer, position, comm); } #define INSTANTIATE_PACK_VECTOR(...) \ template std::size_t packSize(const std::vector<__VA_ARGS__>& data, \ Dune::MPIHelper::MPICommunicator comm); \ template void pack(const std::vector<__VA_ARGS__>& data, \ std::vector& buffer, int& position, \ Dune::MPIHelper::MPICommunicator comm); \ template void unpack(std::vector<__VA_ARGS__>& data, \ std::vector& buffer, int& position, \ Dune::MPIHelper::MPICommunicator comm); INSTANTIATE_PACK_VECTOR(double) INSTANTIATE_PACK_VECTOR(std::vector) INSTANTIATE_PACK_VECTOR(bool) INSTANTIATE_PACK_VECTOR(char) INSTANTIATE_PACK_VECTOR(int) INSTANTIATE_PACK_VECTOR(size_t) INSTANTIATE_PACK_VECTOR(std::time_t) INSTANTIATE_PACK_VECTOR(std::array) INSTANTIATE_PACK_VECTOR(std::pair) INSTANTIATE_PACK_VECTOR(std::shared_ptr) INSTANTIATE_PACK_VECTOR(std::shared_ptr) INSTANTIATE_PACK_VECTOR(std::shared_ptr) INSTANTIATE_PACK_VECTOR(std::shared_ptr) INSTANTIATE_PACK_VECTOR(std::map) INSTANTIATE_PACK_VECTOR(std::pair>) INSTANTIATE_PACK_VECTOR(std::pair>) INSTANTIATE_PACK_VECTOR(std::pair) INSTANTIATE_PACK_VECTOR(std::pair) #undef INSTANTIATE_PACK_VECTOR #define INSTANTIATE_PACK_SET(...) \ template std::size_t packSize(const std::set<__VA_ARGS__>& data, \ Dune::MPIHelper::MPICommunicator comm); \ template void pack(const std::set<__VA_ARGS__>& data, \ std::vector& buffer, int& position, \ Dune::MPIHelper::MPICommunicator comm); \ template void unpack(std::set<__VA_ARGS__>& data, \ std::vector& buffer, int& position, \ Dune::MPIHelper::MPICommunicator comm); INSTANTIATE_PACK_SET(std::string) #undef INSTANTIATE_PACK_SET #define INSTANTIATE_PACK_SHARED_PTR(...) \ template std::size_t packSize(const std::shared_ptr<__VA_ARGS__>& data, \ Dune::MPIHelper::MPICommunicator comm); \ template void pack(const std::shared_ptr<__VA_ARGS__>& data, \ std::vector& buffer, int& position, \ Dune::MPIHelper::MPICommunicator comm); \ template void unpack(std::shared_ptr<__VA_ARGS__>& data, \ std::vector& buffer, int& position, \ Dune::MPIHelper::MPICommunicator comm); INSTANTIATE_PACK_SHARED_PTR(SpiralICD) INSTANTIATE_PACK_SHARED_PTR(VFPInjTable) INSTANTIATE_PACK_SHARED_PTR(Well) #undef INSTANTIATE_PACK_SHARED_PTR #define INSTANTIATE_PACK(...) \ template std::size_t packSize(const __VA_ARGS__& data, \ Dune::MPIHelper::MPICommunicator comm); \ template void pack(const __VA_ARGS__& data, \ std::vector& buffer, int& position, \ Dune::MPIHelper::MPICommunicator comm); \ template void unpack(__VA_ARGS__& data, \ std::vector& buffer, int& position, \ Dune::MPIHelper::MPICommunicator comm); INSTANTIATE_PACK(double) INSTANTIATE_PACK(std::size_t) INSTANTIATE_PACK(bool) INSTANTIATE_PACK(int) INSTANTIATE_PACK(std::array) INSTANTIATE_PACK(std::array) INSTANTIATE_PACK(unsigned char) INSTANTIATE_PACK(std::map,std::pair>) INSTANTIATE_PACK(std::map) INSTANTIATE_PACK(std::map>) INSTANTIATE_PACK(std::map>) INSTANTIATE_PACK(std::map,int>>) INSTANTIATE_PACK(std::map) INSTANTIATE_PACK(std::unordered_map) INSTANTIATE_PACK(std::unordered_map) INSTANTIATE_PACK(std::unordered_set) INSTANTIATE_PACK(std::pair) INSTANTIATE_PACK(std::pair) INSTANTIATE_PACK(DynamicState) INSTANTIATE_PACK(DynamicState>) INSTANTIATE_PACK(DynamicState>) INSTANTIATE_PACK(DynamicState>) INSTANTIATE_PACK(DynamicState>) INSTANTIATE_PACK(DynamicState) INSTANTIATE_PACK(DynamicVector) #undef INSTANTIATE_PACK } // end namespace Mpi RestartValue loadParallelRestart(const EclipseIO* eclIO, SummaryState& summaryState, const std::vector& solutionKeys, const std::vector& extraKeys, Dune::CollectiveCommunication comm) { #if HAVE_MPI data::Solution sol; data::Wells wells; RestartValue restartValues(sol, wells); if (eclIO) { assert(comm.rank() == 0); restartValues = eclIO->loadRestart(summaryState, solutionKeys, extraKeys); int packedSize = Mpi::packSize(restartValues, comm); std::vector buffer(packedSize); int position=0; Mpi::pack(restartValues, buffer, position, comm); comm.broadcast(&position, 1, 0); comm.broadcast(buffer.data(), position, 0); } else { int bufferSize{}; comm.broadcast(&bufferSize, 1, 0); std::vector buffer(bufferSize); comm.broadcast(buffer.data(), bufferSize, 0); int position{}; Mpi::unpack(restartValues, buffer, position, comm); } return restartValues; #else (void) comm; return eclIO->loadRestart(summaryState, solutionKeys, extraKeys); #endif } } // end namespace Opm