From 10e967653b169f15cf5988ebb46c71c74cf05eed Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Fri, 18 Nov 2022 11:57:37 +0100 Subject: [PATCH] added: StandardWellAssemble this handles assembly of the equation system for standardwell. start by moving assembleControlEq into the new class --- CMakeLists_files.cmake | 3 + opm/simulators/wells/StandardWellAssemble.cpp | 187 ++++++++++++++++++ opm/simulators/wells/StandardWellAssemble.hpp | 71 +++++++ opm/simulators/wells/StandardWellEval.cpp | 95 --------- opm/simulators/wells/StandardWellEval.hpp | 6 - opm/simulators/wells/StandardWell_impl.hpp | 14 +- 6 files changed, 274 insertions(+), 102 deletions(-) create mode 100644 opm/simulators/wells/StandardWellAssemble.cpp create mode 100644 opm/simulators/wells/StandardWellAssemble.hpp diff --git a/CMakeLists_files.cmake b/CMakeLists_files.cmake index 05353ddaf..4d7bea348 100644 --- a/CMakeLists_files.cmake +++ b/CMakeLists_files.cmake @@ -96,6 +96,7 @@ list (APPEND MAIN_SOURCE_FILES opm/simulators/wells/PerfData.cpp opm/simulators/wells/SegmentState.cpp opm/simulators/wells/SingleWellState.cpp + opm/simulators/wells/StandardWellAssemble.cpp opm/simulators/wells/StandardWellEquations.cpp opm/simulators/wells/StandardWellEval.cpp opm/simulators/wells/StandardWellGeneric.cpp @@ -381,8 +382,10 @@ list (APPEND PUBLIC_HEADER_FILES opm/simulators/wells/SingleWellState.hpp opm/simulators/wells/StandardWell.hpp opm/simulators/wells/StandardWell_impl.hpp + opm/simulators/wells/StandardWellAssemble.hpp opm/simulators/wells/StandardWellEquations.hpp opm/simulators/wells/StandardWellEval.hpp + opm/simulators/wells/StandardWellGeneric.hpp opm/simulators/wells/TargetCalculator.hpp opm/simulators/wells/VFPHelpers.hpp opm/simulators/wells/VFPInjProperties.hpp diff --git a/opm/simulators/wells/StandardWellAssemble.cpp b/opm/simulators/wells/StandardWellAssemble.cpp new file mode 100644 index 000000000..4aa88ef2c --- /dev/null +++ b/opm/simulators/wells/StandardWellAssemble.cpp @@ -0,0 +1,187 @@ +/* + Copyright 2017 SINTEF Digital, Mathematics and Cybernetics. + Copyright 2017 Statoil ASA. + Copyright 2016 - 2017 IRIS 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 +#include + +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +namespace Opm { + +template +template +void +StandardWellAssemble:: +assembleControlEq(const WellState& well_state, + const GroupState& group_state, + const Schedule& schedule, + const SummaryState& summaryState, + const int numWellEq, + const EvalWell& wqTotal, + const EvalWell& bhp, + const std::function& getQs, + const double rho, + const int Bhp, + StandardWellEquations& eqns, + DeferredLogger& deferred_logger) const +{ + static constexpr int Water = BlackoilPhases::Aqua; + static constexpr int Oil = BlackoilPhases::Liquid; + static constexpr int Gas = BlackoilPhases::Vapour; + EvalWell control_eq(numWellEq + Indices::numEq, 0.0); + + const auto& well = well_.wellEcl(); + + auto getRates = [&]() { + std::vector rates(3, EvalWell(numWellEq + Indices::numEq, 0.0)); + if (FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx)) { + rates[Water] = getQs(Indices::canonicalToActiveComponentIndex(FluidSystem::waterCompIdx)); + } + if (FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx)) { + rates[Oil] = getQs(Indices::canonicalToActiveComponentIndex(FluidSystem::oilCompIdx)); + } + if (FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)) { + rates[Gas] = getQs(Indices::canonicalToActiveComponentIndex(FluidSystem::gasCompIdx)); + } + return rates; + }; + + if (well_.wellIsStopped()) { + control_eq = wqTotal; + } else if (well_.isInjector()) { + // Find injection rate. + const EvalWell injection_rate = wqTotal; + // Setup function for evaluation of BHP from THP (used only if needed). + std::function bhp_from_thp = [&]() { + const auto rates = getRates(); + return WellBhpThpCalculator(well_).calculateBhpFromThp(well_state, + rates, + well, + summaryState, + rho, + deferred_logger); + }; + + // Call generic implementation. + const auto& inj_controls = well.injectionControls(summaryState); + WellAssemble(well_). + assembleControlEqInj(well_state, + group_state, + schedule, + summaryState, + inj_controls, + bhp, + injection_rate, + bhp_from_thp, + control_eq, + deferred_logger); + } else { + // Find rates. + const auto rates = getRates(); + // Setup function for evaluation of BHP from THP (used only if needed). + std::function bhp_from_thp = [&]() { + return WellBhpThpCalculator(well_).calculateBhpFromThp(well_state, + rates, + well, + summaryState, + rho, + deferred_logger); + }; + // Call generic implementation. + const auto& prod_controls = well.productionControls(summaryState); + WellAssemble(well_). + assembleControlEqProd(well_state, + group_state, + schedule, + summaryState, + prod_controls, + bhp, + rates, + bhp_from_thp, + control_eq, + deferred_logger); + } + + // using control_eq to update the matrix and residuals + // TODO: we should use a different index system for the well equations + eqns.resWell_[0][Bhp] = control_eq.value(); + for (int pv_idx = 0; pv_idx < numWellEq; ++pv_idx) { + eqns.duneD_[0][0][Bhp][pv_idx] = control_eq.derivative(pv_idx + Indices::numEq); + } +} + +#define INSTANCE(Dim,...) \ +template class StandardWellAssemble,__VA_ARGS__,double>; \ +template void \ +StandardWellAssemble,__VA_ARGS__,double>:: \ + assembleControlEq(const WellState&, \ + const GroupState&, \ + const Schedule&, \ + const SummaryState&, \ + const int, \ + const DenseAd::Evaluation&, \ + const DenseAd::Evaluation&, \ + const std::function(int)>&, \ + const double, \ + const int, \ + StandardWellEquations&, \ + DeferredLogger&) const; + +// One phase +INSTANCE(4u, BlackOilOnePhaseIndices<0u,0u,0u,0u,false,false,0u,1u,0u>) +INSTANCE(5u, BlackOilOnePhaseIndices<0u,0u,0u,1u,false,false,0u,1u,0u>) +INSTANCE(9u, BlackOilOnePhaseIndices<0u,0u,0u,0u,false,false,0u,1u,5u>) + + // Two phase +INSTANCE(6u, BlackOilTwoPhaseIndices<0u,0u,0u,0u,false,false,0u,0u,0u>) +INSTANCE(6u, BlackOilTwoPhaseIndices<0u,0u,0u,0u,false,false,0u,1u,0u>) +INSTANCE(6u, BlackOilTwoPhaseIndices<0u,0u,0u,0u,false,false,0u,2u,0u>) +INSTANCE(7u, BlackOilTwoPhaseIndices<0u,0u,1u,0u,false,false,0u,2u,0u>) +INSTANCE(7u, BlackOilTwoPhaseIndices<0u,0u,1u,0u,false,true,0u,2u,0u>) +INSTANCE(7u, BlackOilTwoPhaseIndices<0u,0u,0u,1u,false,false,0u,1u,0u>) +INSTANCE(7u, BlackOilTwoPhaseIndices<0u,0u,0u,0u,false,true,0u,0u,0u>) +INSTANCE(7u, BlackOilTwoPhaseIndices<0u,0u,0u,0u,false,true,0u,2u,0u>) +INSTANCE(8u, BlackOilTwoPhaseIndices<0u,0u,2u,0u,false,false,0u,2u,0u>) + + // Blackoil +INSTANCE(8u, BlackOilIndices<0u,0u,0u,0u,false,false,0u,0u>) +INSTANCE(9u, BlackOilIndices<0u,0u,0u,0u,true,false,0u,0u>) +INSTANCE(9u, BlackOilIndices<0u,0u,0u,0u,false,true,0u,0u>) +INSTANCE(9u, BlackOilIndices<0u,1u,0u,0u,false,false,0u,0u>) +INSTANCE(9u, BlackOilIndices<0u,0u,1u,0u,false,false,0u,0u>) +INSTANCE(9u, BlackOilIndices<0u,0u,0u,1u,false,false,0u,0u>) +INSTANCE(10u, BlackOilIndices<1u,0u,0u,0u,false,false,0u,0u>) +INSTANCE(10u, BlackOilIndices<0u,0u,0u,1u,false,true,0u,0u>) +INSTANCE(10u, BlackOilIndices<0u,0u,0u,1u,false,false,1u,0u>) + +} diff --git a/opm/simulators/wells/StandardWellAssemble.hpp b/opm/simulators/wells/StandardWellAssemble.hpp new file mode 100644 index 000000000..1281add71 --- /dev/null +++ b/opm/simulators/wells/StandardWellAssemble.hpp @@ -0,0 +1,71 @@ +/* + Copyright 2017 SINTEF Digital, Mathematics and Cybernetics. + Copyright 2017 Statoil ASA. + Copyright 2016 - 2017 IRIS 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 . +*/ + + +#ifndef OPM_STANDARDWELL_ASSEMBLE_HEADER_INCLUDED +#define OPM_STANDARDWELL_ASSEMBLE_HEADER_INCLUDED + +#include + +namespace Opm +{ + +class DeferredLogger; +class GroupState; +class Schedule; +template class StandardWellEquations; +class SummaryState; +template class WellInterfaceFluidSystem; +class WellState; + +//! \brief Class handling assemble of the equation system for StandardWell. +template +class StandardWellAssemble +{ +public: + //! \brief Constructor initializes reference to well. + StandardWellAssemble(const WellInterfaceFluidSystem& well) + : well_(well) + {} + + //! \brief Assemble control equation. + template + void assembleControlEq(const WellState& well_state, + const GroupState& group_state, + const Schedule& schedule, + const SummaryState& summaryState, + const int numWellEq, + const EvalWell& wqTotal, + const EvalWell& bhp, + const std::function& getQs, + const double rho, + const int Bhp, + StandardWellEquations& eqns, + DeferredLogger& deferred_logger) const; + + +private: + const WellInterfaceFluidSystem& well_; //!< Reference to well +}; + +} + +#endif // OPM_STANDARDWELL_ASSEMBLE_HEADER_INCLUDED diff --git a/opm/simulators/wells/StandardWellEval.cpp b/opm/simulators/wells/StandardWellEval.cpp index 40815ce87..6fc380fef 100644 --- a/opm/simulators/wells/StandardWellEval.cpp +++ b/opm/simulators/wells/StandardWellEval.cpp @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include @@ -358,100 +357,6 @@ updatePrimaryVariables(const WellState& well_state, DeferredLogger& deferred_log primary_variables_[Bhp] = ws.bhp; } -template -void -StandardWellEval:: -assembleControlEq(const WellState& well_state, - const GroupState& group_state, - const Schedule& schedule, - const SummaryState& summaryState, - DeferredLogger& deferred_logger) -{ - static constexpr int Gas = WellInterfaceIndices::Gas; - static constexpr int Oil = WellInterfaceIndices::Oil; - static constexpr int Water = WellInterfaceIndices::Water; - EvalWell control_eq(numWellEq_ + Indices::numEq, 0.0); - - const auto& well = baseif_.wellEcl(); - - auto getRates = [&]() { - std::vector rates(3, EvalWell(numWellEq_ + Indices::numEq, 0.0)); - if (FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx)) { - rates[Water] = getQs(Indices::canonicalToActiveComponentIndex(FluidSystem::waterCompIdx)); - } - if (FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx)) { - rates[Oil] = getQs(Indices::canonicalToActiveComponentIndex(FluidSystem::oilCompIdx)); - } - if (FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)) { - rates[Gas] = getQs(Indices::canonicalToActiveComponentIndex(FluidSystem::gasCompIdx)); - } - return rates; - }; - - if (baseif_.wellIsStopped()) { - control_eq = getWQTotal(); - } else if (baseif_.isInjector()) { - // Find injection rate. - const EvalWell injection_rate = getWQTotal(); - // Setup function for evaluation of BHP from THP (used only if needed). - std::function bhp_from_thp = [&]() { - const auto rates = getRates(); - return WellBhpThpCalculator(baseif_).calculateBhpFromThp(well_state, - rates, - well, - summaryState, - this->getRho(), - deferred_logger); - }; - // Call generic implementation. - const auto& inj_controls = well.injectionControls(summaryState); - WellAssemble(baseif_). - assembleControlEqInj(well_state, - group_state, - schedule, - summaryState, - inj_controls, - getBhp(), - injection_rate, - bhp_from_thp, - control_eq, - deferred_logger); - } else { - // Find rates. - const auto rates = getRates(); - // Setup function for evaluation of BHP from THP (used only if needed). - std::function bhp_from_thp = [&]() { - return WellBhpThpCalculator(baseif_).calculateBhpFromThp(well_state, - rates, - well, - summaryState, - this->getRho(), - deferred_logger); - }; - // Call generic implementation. - const auto& prod_controls = well.productionControls(summaryState); - WellAssemble(baseif_). - assembleControlEqProd(well_state, - group_state, - schedule, - summaryState, - prod_controls, - getBhp(), - rates, - bhp_from_thp, - control_eq, - deferred_logger); - } - - // using control_eq to update the matrix and residuals - // TODO: we should use a different index system for the well equations - this->linSys_.resWell_[0][Bhp] = control_eq.value(); - for (int pv_idx = 0; pv_idx < numWellEq_; ++pv_idx) { - this->linSys_.duneD_[0][0][Bhp][pv_idx] = control_eq.derivative(pv_idx + Indices::numEq); - } -} - - template void StandardWellEval:: diff --git a/opm/simulators/wells/StandardWellEval.hpp b/opm/simulators/wells/StandardWellEval.hpp index 3a18f8a37..00d0b4ece 100644 --- a/opm/simulators/wells/StandardWellEval.hpp +++ b/opm/simulators/wells/StandardWellEval.hpp @@ -133,12 +133,6 @@ protected: static double relaxationFactorFractionsProducer(const std::vector& primary_variables, const BVectorWell& dwells); - void assembleControlEq(const WellState& well_state, - const GroupState& group_state, - const Schedule& schedule, - const SummaryState& summaryState, - DeferredLogger& deferred_logger); - // computing the accumulation term for later use in well mass equations void computeAccumWell(); diff --git a/opm/simulators/wells/StandardWell_impl.hpp b/opm/simulators/wells/StandardWell_impl.hpp index 75b33f5aa..ac6e8d9e8 100644 --- a/opm/simulators/wells/StandardWell_impl.hpp +++ b/opm/simulators/wells/StandardWell_impl.hpp @@ -20,6 +20,7 @@ */ #include +#include #include #include #include @@ -544,7 +545,18 @@ namespace Opm const auto& summaryState = ebosSimulator.vanguard().summaryState(); const Schedule& schedule = ebosSimulator.vanguard().schedule(); - this->assembleControlEq(well_state, group_state, schedule, summaryState, deferred_logger); + std::function gQ = [this](int a) { return this->getQs(a); }; + StandardWellAssemble(*this). + assembleControlEq(well_state, group_state, + schedule, summaryState, + this->numWellEq_, + this->getWQTotal(), + this->getBhp(), + gQ, + this->getRho(), + Bhp, + this->linSys_, + deferred_logger); // do the local inversion of D.