Files
opm-simulators/flowexperimental/comp/wells/CompWellModel.hpp
T
hnilandClaude Fable 5 4374de70b1 Add serializeOp support for compositional types
The standard-flow main pulls in OPMRST (HDF5) save/load state through
SimulatorFullyImplicit, which requires the whole model and problem to be
serializable. Provide serializeOp for FlashPrimaryVariables (plain
FieldVector contents) and empty implementations for EmptyModel and
CompWellModel, where restart support is not implemented yet.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 20:08:03 +02:00

205 lines
7.1 KiB
C++

/*
Copyright 2024, SINTEF Digital
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 <http://www.gnu.org/licenses/>.
*/
#ifndef OPM_COMPOSITIONAL_WELL_MODEL_HPP
#define OPM_COMPOSITIONAL_WELL_MODEL_HPP
#include <opm/output/data/Wells.hpp>
#include <opm/models/discretization/common/baseauxiliarymodule.hh>
#include <opm/input/eclipse/Schedule/Events.hpp>
#include <opm/input/eclipse/Schedule/Well/WellTestState.hpp>
#include <opm/input/eclipse/Schedule/Schedule.hpp>
#include <flowexperimental/comp/wells/CompWell.hpp>
#include <flowexperimental/comp/wells/CompWellState.hpp>
#include <opm/simulators/utils/ParallelCommunication.hpp>
#include <opm/simulators/wells/WellConnectionAuxiliaryModule.hpp>
#include <opm/simulators/wells/PerforationData.hpp>
#include <opm/simulators/timestepping/SimulatorReport.hpp>
#include <map>
#include <vector>
namespace Opm {
class Schedule;
struct NewtonIterationContext;
template<typename TypeTag>
class CompWellModel : public WellConnectionAuxiliaryModule<TypeTag, CompWellModel<TypeTag>>
{
using ElementContext = GetPropType<TypeTag, Properties::ElementContext>;
using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
using GridView = GetPropType<TypeTag, Properties::GridView>;
using GlobalEqVector = GetPropType<TypeTag, Properties::GlobalEqVector>;
using Scalar = GetPropType<TypeTag, Properties::Scalar>;
using RateVector = GetPropType<TypeTag, Properties::RateVector>;
using SparseMatrixAdapter = GetPropType<TypeTag, Properties::SparseMatrixAdapter>;
using CompConnectionData = PerforationData<Scalar>;
// using NeighborSet = typename BaseAuxiliaryModule<TypeTag>::NeighborSet;
public:
using Simulator = GetPropType<TypeTag, Properties::Simulator>;
using WellConnectionModule = WellConnectionAuxiliaryModule<TypeTag, CompWellModel<TypeTag>>;
using Indices = GetPropType<TypeTag, Properties::Indices>;
static const int numEq = Indices::numEq;
using VectorBlockType = Dune::FieldVector<Scalar, numEq>;
typedef Dune::BlockVector<VectorBlockType> BVector;
// TODO: Scalar will probably to be TypeTag later
using CompWellPtr = std::shared_ptr<CompWell<TypeTag> >;
CompWellModel(Simulator& /*simulator*/, const NewtonIterationContext& /*iter_ctx*/);
// No extra dofs are inserted for wells. (we use a Schur complement.)
[[nodiscard]] unsigned numDofs() const override
{ return 0; }
// void addNeighbors(std::vector<NeighborSet>& /* neighbors */) const override
// {}
void applyInitial() override {}
// void linearize(SparseMatrixAdapter& /*matrix*/, GlobalEqVector& /*residual*/) override;
template <class Restarter>
void serialize(Restarter& /*res*/)
{}
template <class Restarter>
void deserialize(Restarter& /*res*/)
{}
// OPMRST restart of compositional wells is not supported yet
template<class Serializer>
void serializeOp(Serializer& /*serializer*/)
{}
void beginEpisode() { beginReportStep(simulator_.episodeIndex()); }
void beginReportStep(unsigned report_step);
void beginTimeStep();
void beginIteration();
void restoreLastValidState();
void init();
void endIteration() const {}
void endTimeStep();
void endEpisode() {}
void computeTotalRatesForDof(RateVector& /*rate*/, unsigned /*globalIdx*/) const;
//
[[nodiscard]] data::Wells wellData() const;
[[nodiscard]] data::WellBlockAveragePressures wellBlockAveragePressures() const {
return data::WellBlockAveragePressures{};
}
[[nodiscard]] data::GroupAndNetworkValues groupAndNetworkData(const int&) const {
return data::GroupAndNetworkValues{};
}
[[nodiscard]] WellTestState wellTestState() const {
return WellTestState{};
}
// using the solution x to recover the solution xw for wells and applying
// xw to update Well State
void recoverWellSolutionAndUpdateWellState(const BVector& x);
// some functions to compile
bool addMatrixContributions() const { return false; }
const Schedule& schedule() const { return schedule_; }
auto begin() const { return well_container_.begin(); }
auto end() const { return well_container_.end(); }
const SimulatorReportSingle& lastReport() const { return last_report_; }
void prepareDeserialize(const int) {}
const std::map<std::string, double>& wellOpenTimes() const { return well_open_times_; }
const std::map<std::string, double>& wellCloseTimes() const { return well_close_times_; }
const WellGroupEvents& reportStepStartEvents() const { return report_step_start_events_; }
bool forceShutWellByName(const std::string& well_name, double simulation_time, bool dont_shut_grup_wells);
template <class ReservoirCouplingSlave>
void setReservoirCouplingSlave(ReservoirCouplingSlave*) {}
template <class ReservoirCouplingMaster>
void setReservoirCouplingMaster(ReservoirCouplingMaster*) {}
bool getWellConvergence() const;
// the following functions are not used while added to avoid modifying WellConnectionAuxiliaryModule.hpp
std::size_t compressedIndexForInterior(std::size_t cartesian_cell_idx) const;
std::vector<int> getCellsForConnections(const Well& well) const;
private:
Simulator& simulator_;
const Schedule& schedule_;
const SummaryState& summary_state_;
const EclipseState& ecl_state_;
const Parallel::Communication& comm_;
// we might need something lighter
const CompositionalConfig& comp_config_;
// we will need two to handle the changes between time stepping
CompWellState<FluidSystem> comp_well_states_;
// saved state at beginning of report step, used to restore on failed timestep
CompWellState<FluidSystem> last_valid_comp_well_states_;
// this is needed for parallel running, not all the wells will be in the same process
std::vector<Well> wells_ecl_;
std::vector<std::vector<CompConnectionData> > well_connection_data_;
// const Schedule& schedule_;
std::vector<CompWellPtr> well_container_;
mutable BVector x_local_;
std::size_t local_num_cells_{0};
SimulatorReportSingle last_report_{};
std::map<std::string, double> well_open_times_;
std::map<std::string, double> well_close_times_;
WellGroupEvents report_step_start_events_{};
void createWellContainer();
void initWellContainer();
void initWellConnectionData();
void initWellState();
void assemble(const double dt);
void calculateExplicitQuantities();
};
} // end of namespace Opm
#include "CompWellModel_impl.hpp"
#endif // OPM_COMPOSITIONAL_WELL_MODEL_HPP